升级sql构建, 支持or语句

This commit is contained in:
白茶清欢 2024-08-09 18:26:30 +08:00
parent 88f9e831d8
commit 7126765fd5
3 changed files with 149 additions and 52 deletions

64
base.go
View File

@ -199,59 +199,19 @@ func (b *BaseDao) setTxCondition(tx *gorm.DB, optionFuncList ...SetOption) *gorm
tx = tx.Offset(o.Offset) tx = tx.Offset(o.Offset)
} }
} }
sqlBlockList := make([]string, 0)
// 设置where条件 bindValueList := make([]any, 0)
if nil != o.Where && len(o.Where) > 0 { sql, bindVal := optionToSql(o)
tx = tx.Where(o.Where) tx.Or(sql, bindVal...)
} sqlBlockList = append(sqlBlockList, sql)
bindValueList = append(bindValueList, bindVal)
// in 语句 for _, itemOrFuncList := range o.OR {
if nil != o.In { orOption := &Option{}
tx = tx.Where(o.In) for _, fn := range itemOrFuncList {
} fn(orOption)
// not in 语句
if nil != o.NotIn {
for field, value := range o.NotIn {
tx = tx.Where(field+" NOT IN ? ", value)
} }
} orSql, orBindVal := optionToSql(orOption)
tx.Or(orSql, orBindVal...)
// like 语句
if nil != o.Like {
for field, value := range o.Like {
tx = tx.Where(field+" LIKE ? ", "%"+value+"%")
}
}
// NOT LIKE 语句
if nil != o.NotLike {
for field, value := range o.NotLike {
tx = tx.Where(field+" NOT LIKE ? ", "%"+value+"%")
}
}
// >=
if nil != o.Start {
for field, value := range o.Start {
tx = tx.Where(field+" >= ?", value)
}
}
// <
if nil != o.End {
for field, value := range o.End {
tx = tx.Where(field+" < ?", value)
}
}
// 排序
for _, orderRule := range o.Order {
tx = tx.Order(orderRule)
}
// or 语句
if len(o.OR) > 0 {
} }
return tx return tx
} }

View File

@ -8,7 +8,10 @@
package database package database
import ( import (
"encoding/json"
"git.zhangdeman.cn/zhangdeman/op_type" "git.zhangdeman.cn/zhangdeman/op_type"
"reflect"
"strings"
) )
// SetOption 设置选项 // SetOption 设置选项
@ -393,3 +396,96 @@ func WithOrderAsc(field string) SetOption {
o.Order = append(o.Order, field+" asc") o.Order = append(o.Order, field+" asc")
} }
} }
// newOption 生成新的option
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 17:46 2024/8/9
func newOption(setOptionList ...SetOption) *Option {
o := &Option{}
for _, item := range setOptionList {
item(o)
}
return o
}
// optionToSql 基于 option 配置生成sql
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 17:46 2024/8/9
func optionToSql(o *Option) (sqlBuildResult string, bindValue []any) {
bindValue = make([]any, 0)
sqlBuildResultBlockList := make([]string, 0)
// 设置where条件
for fieldName, fieldValue := range o.Where {
if nil == fieldValue {
continue
}
if reflect.TypeOf(fieldValue).Kind() == reflect.Slice {
// 传入数组, in语句
sqlBuildResultBlockList = append(sqlBuildResultBlockList, "`"+fieldName+"` in (?)")
byteData, _ := json.Marshal(fieldValue)
bindValue = append(bindValue, strings.TrimRight(strings.TrimLeft(string(byteData), "["), "]"))
} else {
sqlBuildResultBlockList = append(sqlBuildResultBlockList, "`"+fieldName+"` = ?")
bindValue = append(bindValue, fieldValue)
}
}
// 设置不等于
for fieldName, fieldValue := range o.NotEqual {
sqlBuildResultBlockList = append(sqlBuildResultBlockList, "`"+fieldName+"` != ?")
bindValue = append(bindValue, fieldValue)
}
// in 语句
// 传入数组, in语句
for fieldName, fieldValue := range o.In {
sqlBuildResultBlockList = append(sqlBuildResultBlockList, "`"+fieldName+"` in (?)")
byteData, _ := json.Marshal(fieldValue)
bindValue = append(bindValue, strings.TrimRight(strings.TrimLeft(string(byteData), "["), "]"))
}
// not in 语句
for fieldName, fieldValue := range o.NotIn {
sqlBuildResultBlockList = append(sqlBuildResultBlockList, "`"+fieldName+"` NOT IN (?)")
byteData, _ := json.Marshal(fieldValue)
bindValue = append(bindValue, strings.TrimRight(strings.TrimLeft(string(byteData), "["), "]"))
}
// like 语句
for fieldName, fieldValue := range o.Like {
if len(fieldValue) == 0 {
continue
}
sqlBuildResultBlockList = append(sqlBuildResultBlockList, "`"+fieldName+"` LIKE \"%?%\"")
bindValue = append(bindValue, fieldValue)
}
// NOT LIKE 语句
for fieldName, fieldValue := range o.NotLike {
if len(fieldValue) == 0 {
continue
}
sqlBuildResultBlockList = append(sqlBuildResultBlockList, "`"+fieldName+"` NOT LIKE \"%?%\"")
bindValue = append(bindValue, fieldValue)
}
// >=
for fieldName, fieldValue := range o.Start {
sqlBuildResultBlockList = append(sqlBuildResultBlockList, "`"+fieldName+"` >= ?")
bindValue = append(bindValue, fieldValue)
}
// <
for fieldName, fieldValue := range o.End {
sqlBuildResultBlockList = append(sqlBuildResultBlockList, "`"+fieldName+"` < ?")
bindValue = append(bindValue, fieldValue)
}
if len(bindValue) > 0 {
sqlBuildResult = strings.Join(sqlBuildResultBlockList, " AND ")
}
return
}

41
option_test.go Normal file
View File

@ -0,0 +1,41 @@
// Package database ...
//
// Description : database ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2024-08-09 18:19
package database
import (
"fmt"
"testing"
)
func Test_optionToSql(t *testing.T) {
type args struct {
o *Option
}
o := &Option{
In: nil,
NotIn: nil,
Where: map[string]any{
"name": []string{"zhang", "baicha"},
"age": 18,
},
Start: nil,
End: nil,
Like: map[string]string{
"name": "de",
},
NotLike: map[string]string{
"name": "zhang",
},
NotEqual: map[string]any{
"a": 123,
},
Order: nil,
OR: nil,
}
fmt.Println(optionToSql(o))
}