|
|
@@ -0,0 +1,430 @@
|
|
|
+# 高级查询使用说明
|
|
|
+
|
|
|
+## 概述
|
|
|
+
|
|
|
+高级查询模块提供了类似 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` 类型
|