feat(db): 实现数据库查询中的数组参数展开和空数组处理

- 在 Get 方法中添加无参数时的默认字段和 LIMIT 1 处理
- 实现 expandArrayPlaceholder 方法,自动展开 IN (?) 和 NOT IN (?) 中的数组参数
- 为空数组的 IN 条件生成 1=0 永假条件,NOT IN 生成 1=1 永真条件
- 在 queryWithRetry 和 execWithRetry 中集成数组占位符预处理
- 修复 where.go 中空切片条件的处理逻辑
- 添加完整的 IN/NOT IN 数组查询测试用例
- 更新 .gitignore 规则格式
This commit is contained in:
2026-01-22 07:16:42 +08:00
parent 595275e747
commit 60a12a09bd
7 changed files with 756 additions and 447 deletions
+31 -3
View File
@@ -90,10 +90,29 @@ func (that *HoTimeDB) where(data Map) (string, []interface{}) {
}
// 处理普通条件字段
// 空切片的 IN 条件应该生成永假条件(1=0),而不是跳过
if v != nil && reflect.ValueOf(v).Type().String() == "common.Slice" && len(v.(Slice)) == 0 {
// 检查是否是 NOT IN(带 [!] 后缀)- NOT IN 空数组永真,跳过即可
if !strings.HasSuffix(k, "[!]") {
// IN 空数组 -> 生成永假条件
if normalCondCount > 0 {
where += " AND "
}
where += "1=0 "
normalCondCount++
}
continue
}
if v != nil && strings.Contains(reflect.ValueOf(v).Type().String(), "[]") && len(ObjToSlice(v)) == 0 {
// 检查是否是 NOT IN(带 [!] 后缀)- NOT IN 空数组永真,跳过即可
if !strings.HasSuffix(k, "[!]") {
// IN 空数组 -> 生成永假条件
if normalCondCount > 0 {
where += " AND "
}
where += "1=0 "
normalCondCount++
}
continue
}
@@ -110,17 +129,22 @@ func (that *HoTimeDB) where(data Map) (string, []interface{}) {
}
// 添加 WHERE 关键字
if len(where) != 0 {
// 先去除首尾空格,检查是否有实际条件内容
trimmedWhere := strings.TrimSpace(where)
if len(trimmedWhere) != 0 {
hasWhere := true
for _, v := range vcond {
if strings.Index(where, v) == 0 {
if strings.Index(trimmedWhere, v) == 0 {
hasWhere = false
}
}
if hasWhere {
where = " WHERE " + where + " "
where = " WHERE " + trimmedWhere + " "
}
} else {
// 没有实际条件内容,重置 where
where = ""
}
// 处理特殊字符(按固定顺序:GROUP, HAVING, ORDER, LIMIT, OFFSET
@@ -322,6 +346,8 @@ func (that *HoTimeDB) handleDefaultCondition(k string, v interface{}, where stri
if reflect.ValueOf(v).Type().String() == "common.Slice" || strings.Contains(reflect.ValueOf(v).Type().String(), "[]") {
vs := ObjToSlice(v)
if len(vs) == 0 {
// IN 空数组 -> 生成永假条件
where += "1=0 "
return where, res
}
@@ -352,6 +378,8 @@ func (that *HoTimeDB) handlePlainField(k string, v interface{}, where string, re
} else if reflect.ValueOf(v).Type().String() == "common.Slice" || strings.Contains(reflect.ValueOf(v).Type().String(), "[]") {
vs := ObjToSlice(v)
if len(vs) == 0 {
// IN 空数组 -> 生成永假条件
where += "1=0 "
return where, res
}