添加默认配置触发器相关的文档

This commit is contained in:
2025-11-16 23:17:03 +08:00
parent e8ae756df1
commit 76d498b9a3
3 changed files with 101 additions and 2 deletions

Binary file not shown.

View File

@@ -0,0 +1,101 @@
## 使用触发器在 SQLite3 数据表内实现唯一的默认配置
系统设计了 `RequestInfo``ProxySetting` 两个实体类来配置请求信息和代理设置,对应到 SQLite 表中分别是 `request_info``proxy_setting`,两者都有 `is_default` 字段。
由于同一时间内,数据表中只能存在一条 `is_default` 为 1 的记录,所以要进行一些设置。按照传统方法,需要在 Java 代码中,任何对数据记录 CRUD 的地方进行限制,但由于需要覆写的方法太多,又容易有纰漏,所以直接在数据表内用触发器限制。
`proxy_setting` 表为例,我们需要 5 个触发器来实现这个功能。
### AFTER INSERT is_default = 1 时的触发器
```sqlite
CREATE TRIGGER default_1_after_insert_proxy_setting
AFTER INSERT
ON proxy_setting
FOR EACH ROW
WHEN CAST (NEW.is_default AS INTEGER) = 1
BEGIN
UPDATE proxy_setting
SET is_default = 0
WHERE is_default = 1 AND
id <> NEW.id;
END;
```
在 INSERT 之后,对每一行,如果 is_default = 1 的,如果旧记录有 is_default = 1 的,将旧记录 is_default 置为 0.
### AFTER UPDATE is_default = 1 时的触发器
```sqlite
CREATE TRIGGER default_1_after_update_proxy_setting
AFTER UPDATE
ON proxy_setting
FOR EACH ROW
WHEN CAST (NEW.is_default AS INTEGER) = 1
BEGIN
UPDATE proxy_setting
SET is_default = 0
WHERE id <> NEW.id AND
is_default = 1;
END;
```
和 INSERT 类似,但是 UPDATE 场景。
### BEFORE INSERT is_default = 0 时的触发器
```sqlite
CREATE TRIGGER default_0_before_insert_proxy_setting
BEFORE INSERT
ON proxy_setting
FOR EACH ROW
WHEN NEW.is_default = 0 AND
(
SELECT COUNT( * )
FROM proxy_setting
WHERE is_default = 1
)
= 0
BEGIN
SELECT RAISE(ABORT, "需要配置一条默认代理");
END;
```
在插入之前,如果本条为 0 且数据表内不包含默认配置(即 is_default = 1的记录不允许插入。
### BEFORE UPDATE is_default = 0 时的触发器
```sqlite
CREATE TRIGGER default_0_before_update_proxy_setting
BEFORE UPDATE
ON proxy_setting
FOR EACH ROW
WHEN NEW.is_default = 0 AND
(
SELECT COUNT( * )
FROM proxy_setting
WHERE is_default = 1 AND
id <> NEW.id
)
= 0
BEGIN
SELECT RAISE(ABORT, "需要配置一条默认代理");
END;
```
和 INSERT 场景类似。
### BEFORE DELETE 触发器
```sqlite
CREATE TRIGGER protect_default_proxy_setting
BEFORE DELETE
ON proxy_setting
FOR EACH ROW
WHEN OLD.is_default = 1
BEGIN
SELECT RAISE(ABORT, "待删除数据中有默认代理,不允许删除!");
END;
```
如果待删除的记录中包含默认配置,则不允许删除。

View File

@@ -1,2 +0,0 @@
## 使用触发器在 SQLite3 数据表内实现唯一的默认配置