From 76d498b9a3ab5b95ef1ac7a9e7c208d7000d9d85 Mon Sep 17 00:00:00 2001 From: Doghole Date: Sun, 16 Nov 2025 23:17:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=BB=98=E8=AE=A4=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E8=A7=A6=E5=8F=91=E5=99=A8=E7=9B=B8=E5=85=B3=E7=9A=84?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/database.db | Bin 49152 -> 49152 bytes ...fault-true-in-sqlite3-datatable-trigger.md | 101 ++++++++++++++++++ ...fault-true-in-sqlite3-datatable-trigger.md | 2 - 3 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 src/main/resources/docs/only-one-default-true-in-sqlite3-datatable-trigger.md delete mode 100644 src/main/resources/only-one-default-true-in-sqlite3-datatable-trigger.md diff --git a/src/main/resources/database.db b/src/main/resources/database.db index 4779ce043e52d25a42b0e8c08086c0e394216db2..4f266790be0073fbc054c8d93aab31b5f5bfdb49 100644 GIT binary patch delta 578 zcmZo@U~Xt&o**rFlYxPO2a1`1^qGk|#*8;NCM=O>X5xRmnO)&FKO^Vn$NF*#vdohi zxS1jt_(w=9DCM=}>i!w(!XfQKFLzBG>6D zC^)&gd-^E^yZX2~hbV9 z>`?8K8H0r#A#9+oAXkOV6a^bQ1wYqtz04Gt6^?!`3Yo?6DXD3Rr8y-EwhD&U3a)-G zKtHYlyD<`MvTYFO1zX<2h(k#lx?{}Abj;?dQA~_X za`BTDgX9+fiDle;E`Wz^Q$!Hs=IPO_jGGep9N74+L2$F8f;xY_947~Zw5U82Cx@G- zi;ItIkVi;JKu&&gVopYWaf#9npx+z_$SdHJmt%&S&*_$#l9H2JglhieUF$U&IVRuP JFSBTa005~Jngjp< delta 341 zcmZo@U~Xt&o**rFhJk^B2a1`1^nr;w#*Ak+CM=O>X6C=JnO)&FKO^(z$NF*#vRq{h z+zjU!xTkRjvj1nh$vT5&BC|b{9K$)@+gwv8PTa70Za5Dcr*b5_bf`K&Glm$=L4Lm$qAXEw_EzdKDL0&pom803W zq$o2zJ+&w$H7&6;rzGAmJ~6E%b#rwn6XWLJajcA7e1912r2~N~y(fFKOHW?U!8f^q z!*25XurQ#V;VKLaj84*_svIr+P=kt63rkarOX4&0((>bzGg6!6;wOKIkXt-AjFAPX zm}T)XR>n;Ud=8rx6^i&()tNaNq($YKI62wfGE-7=Qj0u7LIQH~lM{2~m^mO)9Fv!> Pw`1g-d}qJRq74E7M&f3p diff --git a/src/main/resources/docs/only-one-default-true-in-sqlite3-datatable-trigger.md b/src/main/resources/docs/only-one-default-true-in-sqlite3-datatable-trigger.md new file mode 100644 index 0000000..e05b90e --- /dev/null +++ b/src/main/resources/docs/only-one-default-true-in-sqlite3-datatable-trigger.md @@ -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; +``` + +如果待删除的记录中包含默认配置,则不允许删除。 \ No newline at end of file diff --git a/src/main/resources/only-one-default-true-in-sqlite3-datatable-trigger.md b/src/main/resources/only-one-default-true-in-sqlite3-datatable-trigger.md deleted file mode 100644 index 87ff934..0000000 --- a/src/main/resources/only-one-default-true-in-sqlite3-datatable-trigger.md +++ /dev/null @@ -1,2 +0,0 @@ -## 使用触发器在 SQLite3 数据表内实现唯一的默认配置 -