diff --git a/base.go b/base.go index 2bc37b8..0b20801 100644 --- a/base.go +++ b/base.go @@ -199,59 +199,19 @@ func (b *BaseDao) setTxCondition(tx *gorm.DB, optionFuncList ...SetOption) *gorm tx = tx.Offset(o.Offset) } } - - // 设置where条件 - if nil != o.Where && len(o.Where) > 0 { - tx = tx.Where(o.Where) - } - - // in 语句 - if nil != o.In { - tx = tx.Where(o.In) - } - - // not in 语句 - if nil != o.NotIn { - for field, value := range o.NotIn { - tx = tx.Where(field+" NOT IN ? ", value) + sqlBlockList := make([]string, 0) + bindValueList := make([]any, 0) + sql, bindVal := optionToSql(o) + tx.Or(sql, bindVal...) + sqlBlockList = append(sqlBlockList, sql) + bindValueList = append(bindValueList, bindVal) + for _, itemOrFuncList := range o.OR { + orOption := &Option{} + for _, fn := range itemOrFuncList { + fn(orOption) } - } - - // 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 { + orSql, orBindVal := optionToSql(orOption) + tx.Or(orSql, orBindVal...) } return tx } diff --git a/option.go b/option.go index 293e6dc..e0bd1ee 100644 --- a/option.go +++ b/option.go @@ -8,7 +8,10 @@ package database import ( + "encoding/json" "git.zhangdeman.cn/zhangdeman/op_type" + "reflect" + "strings" ) // SetOption 设置选项 @@ -393,3 +396,96 @@ func WithOrderAsc(field string) SetOption { 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 +} diff --git a/option_test.go b/option_test.go new file mode 100644 index 0000000..db8b325 --- /dev/null +++ b/option_test.go @@ -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)) +}