# 高级查询使用说明 ## 概述 高级查询模块提供了类似 Navicat 数据筛选的灵活查询条件构建能力,支持复杂的条件组合和嵌套。 ## 核心概念 ### 1. 查询操作符 (QueryOperator) | 操作符 | 常量 | 说明 | 示例 | |--------|------|------|------| | 等于 | `OperatorEqual` | 字段值等于指定值 | `name = "测试"` | | 不等于 | `OperatorNotEqual` | 字段值不等于指定值 | `status != "deleted"` | | 大于 | `OperatorGreaterThan` | 字段值大于指定值 | `quantity > 10` | | 大于等于 | `OperatorGreaterEqual` | 字段值大于等于指定值 | `price >= 100` | | 小于 | `OperatorLessThan` | 字段值小于指定值 | `stock < 50` | | 小于等于 | `OperatorLessEqual` | 字段值小于等于指定值 | `age <= 18` | | 包含 | `OperatorLike` | 字段值包含指定字符串 | `name LIKE "%测试%"` | | 不包含 | `OperatorNotLike` | 字段值不包含指定字符串 | `name NOT LIKE "%测试%"` | | 开头是 | `OperatorStartsWith` | 字段值以指定字符串开头 | `code LIKE "ABC%"` | | 结尾是 | `OperatorEndsWith` | 字段值以指定字符串结尾 | `email LIKE "%@qq.com"` | | 为空 | `OperatorIsNull` | 字段值为 NULL | `deleted_at IS NULL` | | 不为空 | `OperatorIsNotNull` | 字段值不为 NULL | `email IS NOT NULL` | | 在列表中 | `OperatorIn` | 字段值在指定列表中 | `status IN ('active', 'pending')` | | 不在列表中 | `OperatorNotIn` | 字段值不在指定列表中 | `status NOT IN ('deleted', 'archived')` | ### 2. 逻辑操作符 (LogicOperator) | 操作符 | 常量 | 说明 | |--------|------|------| | 与 | `LogicAnd` | 所有条件都必须满足 | | 或 | `LogicOr` | 满足任意一个条件即可 | ### 3. 数据结构 ```go // 单个查询条件 type QueryCondition struct { Field string // 字段名 Operator QueryOperator // 操作符 Value any // 比较值(可选) } // 条件项(可以是单个条件或嵌套的条件组) type ConditionItem struct { Condition *ConditionGroup // 嵌套条件组 SingleCondition *QueryCondition // 单个条件 } // 条件组 type ConditionGroup struct { Conditions []ConditionItem // 条件列表 Logic LogicOperator // 组内逻辑关系 } // 高级查询参数 type AdvancedQueryParams struct { ConditionGroups []ConditionGroup // 条件组列表 GroupLogic LogicOperator // 组间逻辑关系 } ``` ## 快捷函数 ### 单条件快捷函数 ```go // 等于 Equal("name", "测试资源") // 不等于 NotEqual("status", "deleted") // 大于 GreaterThan("quantity", 10) // 大于等于 GreaterEqual("price", 100) // 小于 LessThan("stock", 50) // 小于等于 LessEqual("age", 18) // 包含(模糊匹配) Like("name", "测试") // 不包含 NotLike("name", "测试") // 开头是 StartsWith("code", "ABC") // 结尾是 EndsWith("email", "@qq.com") // 为空 IsNull("deleted_at") // 不为空 IsNotNull("email") // 在列表中 In("category", []any{"设备", "耗材", "工具"}) // 不在列表中 NotIn("status", []any{"deleted", "archived"}) ``` ### 条件组快捷函数 ```go // AND 条件组(所有条件都必须满足) AndGroup( Equal("name", "测试"), GreaterThan("quantity", 10), IsNotNull("code"), ) // OR 条件组(满足任意一个条件即可) OrGroup( Equal("category", "设备"), Equal("category", "耗材"), Like("name", "测试"), ) ``` ### 完整查询快捷函数 ```go // AND 查询(所有条件组都必须满足) AndQuery( AndGroup(Equal("name", "测试"), GreaterThan("quantity", 10)), OrGroup(Equal("category", "设备"), Equal("category", "耗材")), ) // OR 查询(满足任意一个条件组即可) OrQuery( AndGroup(Equal("status", "active"), GreaterThan("quantity", 0)), AndGroup(Equal("status", "pending"), IsNotNull("approved_by")), ) ``` ## 使用示例 ### 示例 1:简单条件查询 查询名称包含"测试"且数量大于 10 的资源: ```go params := managesdk.QueryResourcesParams{ TenantID: "tenant123", AdvancedQuery: &managesdk.AdvancedQueryParams{ ConditionGroups: []managesdk.ConditionGroup{ managesdk.AndGroup( managesdk.Like("name", "测试"), managesdk.GreaterThan("quantity", 10), ), }, GroupLogic: managesdk.LogicAnd, }, BaseQueryParams: managesdk.BaseQueryParams{ PageNo: 1, PageSize: 10, }, } result, err := client.Manage().Query(params) ``` 等价于 SQL: ```sql WHERE (name LIKE '%测试%' AND quantity > 10) ``` ### 示例 2:OR 条件查询 查询分类为"设备"或"耗材"的资源: ```go params := managesdk.QueryResourcesParams{ TenantID: "tenant123", AdvancedQuery: &managesdk.AdvancedQueryParams{ ConditionGroups: []managesdk.ConditionGroup{ managesdk.OrGroup( managesdk.Equal("category", "设备"), managesdk.Equal("category", "耗材"), ), }, GroupLogic: managesdk.LogicAnd, }, PageNo: 1, PageSize: 10, } ``` 等价于 SQL: ```sql WHERE (category = '设备' OR category = '耗材') ``` ### 示例 3:使用 IN 操作符 查询多个分类的资源: ```go params := managesdk.QueryResourcesParams{ TenantID: "tenant123", AdvancedQuery: &managesdk.AdvancedQueryParams{ ConditionGroups: []managesdk.ConditionGroup{ { Conditions: []managesdk.ConditionItem{ managesdk.In("category", []any{"设备", "耗材", "工具"}), }, Logic: managesdk.LogicAnd, }, }, GroupLogic: managesdk.LogicAnd, }, PageNo: 1, PageSize: 10, } ``` 等价于 SQL: ```sql WHERE category IN ('设备', '耗材', '工具') ``` ### 示例 4:复杂嵌套查询 查询满足以下条件的资源: - (名称包含"测试" AND 数量 > 10) OR (分类是"设备" AND 状态不为空) ```go params := managesdk.QueryResourcesParams{ TenantID: "tenant123", AdvancedQuery: managesdk.OrQuery( managesdk.AndGroup( managesdk.Like("name", "测试"), managesdk.GreaterThan("quantity", 10), ), managesdk.AndGroup( managesdk.Equal("category", "设备"), managesdk.IsNotNull("status"), ), ), PageNo: 1, PageSize: 10, } ``` 等价于 SQL: ```sql WHERE ((name LIKE '%测试%' AND quantity > 10) OR (category = '设备' AND status IS NOT NULL)) ``` ### 示例 5:多条件组组合 查询满足以下条件的资源: - (名称包含"测试" AND 数量 > 10) - AND (分类是"设备" OR 分类是"耗材") - AND (状态不为空) ```go params := managesdk.QueryResourcesParams{ TenantID: "tenant123", AdvancedQuery: managesdk.AndQuery( // 条件组1:名称和数量 managesdk.AndGroup( managesdk.Like("name", "测试"), managesdk.GreaterThan("quantity", 10), ), // 条件组2:分类 managesdk.OrGroup( managesdk.Equal("category", "设备"), managesdk.Equal("category", "耗材"), ), // 条件组3:状态 managesdk.AndGroup( managesdk.IsNotNull("status"), ), ), PageNo: 1, PageSize: 10, } ``` 等价于 SQL: ```sql WHERE ((name LIKE '%测试%' AND quantity > 10) AND (category = '设备' OR category = '耗材') AND (status IS NOT NULL)) ``` ### 示例 6:深层嵌套查询 查询满足以下条件的资源: - ((名称包含"A" OR 名称包含"B") AND 数量 > 0) OR ((分类是"设备" AND 状态是"可用")) ```go params := managesdk.QueryResourcesParams{ TenantID: "tenant123", AdvancedQuery: managesdk.OrQuery( // 条件组1 managesdk.AndGroup( // 嵌套的 OR 条件 managesdk.NewNestedConditionGroup( managesdk.OrGroup( managesdk.Like("name", "A"), managesdk.Like("name", "B"), ), ), managesdk.GreaterThan("quantity", 0), ), // 条件组2 managesdk.AndGroup( managesdk.Equal("category", "设备"), managesdk.Equal("status", "available"), ), ), PageNo: 1, PageSize: 10, } ``` 等价于 SQL: ```sql WHERE (((name LIKE '%A%' OR name LIKE '%B%') AND quantity > 0) OR (category = '设备' AND status = 'available')) ``` ### 示例 7:范围查询 查询数量在 10 到 100 之间的资源: ```go params := managesdk.QueryResourcesParams{ TenantID: "tenant123", AdvancedQuery: &managesdk.AdvancedQueryParams{ ConditionGroups: []managesdk.ConditionGroup{ managesdk.AndGroup( managesdk.GreaterEqual("quantity", 10), managesdk.LessEqual("quantity", 100), ), }, GroupLogic: managesdk.LogicAnd, }, PageNo: 1, PageSize: 10, } ``` 等价于 SQL: ```sql WHERE (quantity >= 10 AND quantity <= 100) ``` ### 示例 8:空值判断 查询未删除的资源(deleted_at 为空): ```go params := managesdk.QueryResourcesParams{ TenantID: "tenant123", AdvancedQuery: &managesdk.AdvancedQueryParams{ ConditionGroups: []managesdk.ConditionGroup{ managesdk.AndGroup( managesdk.IsNull("deleted_at"), ), }, GroupLogic: managesdk.LogicAnd, }, PageNo: 1, PageSize: 10, } ``` 等价于 SQL: ```sql WHERE deleted_at IS NULL ``` ## 与传统查询参数配合使用 高级查询可以与传统查询参数配合使用: ```go params := managesdk.QueryResourcesParams{ TenantID: "tenant123", Name: "测试", // 传统参数:名称筛选 BusinessType: "mbrms", // 传统参数:业务类型 AdvancedQuery: managesdk.AndQuery( // 高级查询:额外条件 managesdk.GreaterThan("quantity", 10), managesdk.IsNotNull("code"), ), PageNo: 1, PageSize: 10, } ``` 传统参数会先应用,然后再应用高级查询条件。 ## 最佳实践 ### 1. 性能优化 - 对于大表查询,优先使用 `Equal`、`In` 等精确匹配操作符 - 避免在大文本字段上使用 `Like` 操作符 - 合理使用索引字段进行查询 ### 2. 条件组织 - 将选择性高的条件放在前面 - 合理分组,避免过深的嵌套层级 - 使用语义化的条件组命名(通过代码注释) ### 3. 安全性 - 字段名应该使用白名单验证 - 避免直接拼接用户输入到查询条件 ## 注意事项 1. **字段名映射**:确保使用的字段名与数据库字段名一致 2. **类型匹配**:比较值的类型应与字段类型匹配 3. **NULL 处理**:`IsNull` 和 `IsNotNull` 不需要 Value 参数 4. **数组参数**:`In` 和 `NotIn` 的 Value 应该是 `[]any` 类型