diff --git a/knowledge.md b/knowledge.md index f0f6b07..b60f098 100644 --- a/knowledge.md +++ b/knowledge.md @@ -720,9 +720,7 @@ meeting_with_room_and_agenda_wo示例: - 列表对象属性只能使用contains、isNull、isNotNull操作符:wo列表类型可用contains(子查询),表示列表属性中需包含至少一个满足子查询条件的对象;其他列表类型只能用isNull或isNotNull - 通过and, or, not连接符拼装子查询完成查询。不要使用未提及的操作符号、连接符 - TOCO读方案查询语法和代码有本质区别,不支持对变量的值进行判断,如#nameLike isNull 或 #name == 'ABC' 或#name isNullOrNot false都属于非法语句 - - 查询条件中的变量可在运行时传入或不传入值(等同于传入Null),不传入值(等同于传Null)表示该变量相关条件不起作用;基于这种动态效果,多条件联合查询可优先使用AND。这个动态能力是由TOCO框架自动完成的,当变量不传入值(或传入Null)直接自动生效,禁止再为动态性编写特定的判空语句,以下为使用示例: - - 对于查询语句 id == #idIs AND name like #nameLike,如果变量#nameLike不传入值(或传入Null),则此时 name like #nameLike 不生效,只有 id == #idIs 会生效 - - 特别注意禁止为动态性编写特定的判空语句,以下语句为非法: id == #idIs AND (name like #nameLike or #nameLike isNull or #nameLike isNullOrNot false),其中 #nameLike isNull 和 #nameLike isNullOrNot false是多余无用的,而且有语法错误 + - 查询条件中的变量可在运行时传入或不传入值,不传入值表示该变量相关条件不起作用;基于这种动态效果,多条件联合查询可优先使用AND。这个动态能力是由TOCO框架自动完成的,当变量不传入值直接自动生效,禁止再为动态性编写特定的判空语句。具体原则严格参照 **[TOCO最佳实践]** 中的**[4.4 参数动态性机制详解]** - 使用点号(.)访问当前对象的单值对象类型子属性,可多个点号组合访问嵌套单值对象属性 - 查询条件中的属性必须是当前查询对象的属性或单值对象属性或单值对象子属性 - 禁止使用filter语法 @@ -1754,7 +1752,7 @@ TOCO严格遵照分层规则,必须严格遵守,否则会产生严重后果 #### 4.3 聚合校验识别与实现指南 -##### 1. 业务不变性规则的明确判断标准 +##### 4.3.1 业务不变性规则的明确判断标准 **必须放在聚合校验中的场景(四个核心判断标准):** @@ -1803,11 +1801,80 @@ TOCO严格遵照分层规则,必须严格遵守,否则会产生严重后果 - 会严重影响性能的校验 - **实现位置**:Service层 -##### 2. 实现注意事项 +##### 4.3.2 实现注意事项 - 聚合校验方法会在写方案执行数据库操作前自动调用 - 禁止在业务代码中显式调用validateAggregate()或valid()方法 - 如果校验逻辑需要查询数据库或调用RPC,不要放在聚合校验中 - 聚合校验应该是纯内存操作,执行速度快 +#### 4.4 参数动态性机制详解 + +##### 核心规则:框架自动处理参数的null值 +当查询条件中包含参数时,如果该参数不传入时, +框架自动让包含该参数的条件不生效。 + +##### 什么是"参数动态性"? + +是指查询语句可以根据**实际传入的参数值**动态调整查询逻辑, +无需编写额外的if-else判断或手动判空语句。 + +##### 动态性的三种情况 + +###### 情况1:参数传入具体值或null +查询语句:status == #statusIs +实际调用:queryPlan(statusIs='PENDING') 或 queryPlan(statusIs= null) +结果:只查询状态为PENDING的预约 + +###### 情况2:参数不传入 +查询语句:status == #statusIs +实际调用:queryPlan() +结果:框架自动跳过此条件,不对状态进行过滤 + +###### 情况3:多个条件的组合 +查询语句: + appointment_status == #statusIs + AND appointment_date >= #startDate + AND examinee_name like #searchKeyword + +实际调用情况A:queryPlan(statusIs='ACTIVE', startDate='2024-01-01', searchKeyword='李') +结果:三个条件都生效,进行完整过滤 + +实际调用情况B:queryPlan(statusIs='ACTIVE', startDate=null, searchKeyword不传) +结果:只有前2个条件生效,最后一个自动跳过 + +实际调用情况C:queryPlan(statusIs不传, startDate不传, searchKeyword不传) +结果:三个条件都跳过,返回所有记录(等价于无过滤条件) + +##### ❌ 禁止为动态性手动编写判空逻辑 + +禁止这样写: + appointment_status == #statusIs + OR (#statusIs isNull) // ❌ 多余且错误! + +禁止这样写: + (appointment_status == #statusIs OR #statusIs isNullOrNot false) // ❌ 错误! + +禁止这样写: + IF #statusIs is not null THEN appointment_status == #statusIs // ❌ SQL不支持! + +##### ✅ 正确的做法 + +直接写条件,相信框架的自动处理: + appointment_status == #statusIs AND time_slot == #timeSlot + +框架会自动处理每个参数不传或为null情况,无需手动干预。 + +##### 为什么禁止手动判空? + +1. **框架已自动实现**:TOCO框架内部有参数解析机制, + 自动将参数不传转换为"条件不生效"的效果 + +2. **重复代码**:手动编写判空会导致代码冗余和重复 + +3. **引入错误**:手动判空容易出错,尤其是复杂条件组合时 + +4. **维护困难**:如果参数数量变化,手动判空逻辑也要改, + 而框架自动处理无需任何改动 + -----------------------------------------------------------------------------