一、上案例
func GetAnalysisWorkers(cond CondGetDetails) (i interface{}, err error) { detail := cond.Detail.(map[string]interface{}) //detail := cond.Detail.(*User) var visualizationDatas []AnalysisWorker var tx *gorm.DB if cond.Keyword != "" { delete(detail, "name") delete(detail, "org_name") // 关键点 tx = DB.Debug().Where("name like @name OR org_name LIKE @org_name", sql.Named("name", "%"+cond.Keyword+"%"), sql.Named("org_name", "%"+cond.Keyword+"%")).Where(detail) } else { tx = DB.Debug().Where(detail) } err = tx.Debug().Preload(clause.Associations).Limit(cond.PageSize).Offset(cond.PageAfter).Order(cond.OrderBy + " " + cond.SortBy).Find(&visualizationDatas).Error return visualizationDatas, err }
- 这端代码的关键指出就是上述中的两个Where 子句(
tx = DB.Debug().Where("name like @name OR org_name LIKE @org_name", sql.Named("name", "%"+cond.Keyword+"%"), sql.Named("org_name", "%"+cond.Keyword+"%")).Where(detail)
)
这两个Where 子句的本意转换成sql是这样的:
SELECT * FROM `analysis_worker` WHERE name like '%张亮%' OR org_name LIKE '%张亮%' AND `period` = 2022001 AND `analysis_worker`.`deleted_at` IS NULL ORDER BY org_name desc LIMIT 10
但本意是下面这样的:
SELECT * FROM `analysis_worker` WHERE (name like '%张亮%' OR org_name LIKE '%张亮%') AND `period` = 2022001 AND `analysis_worker`.`deleted_at` IS NULL ORDER BY org_name desc LIMIT 10
- 说白了,就是多了个括号和少了个括号的区别,这影响可大了——全部都是 and 条件,那无所谓,一旦涉及到 or 条件,就天差地别了。
解决办法:
func GetAnalysisWorkers(cond CondGetDetails) (i interface{}, err error) { detail := cond.Detail.(map[string]interface{}) //detail := cond.Detail.(*User) var visualizationDatas []AnalysisWorker var tx *gorm.DB if cond.Keyword != "" { delete(detail, "name") delete(detail, "org_name") // 加上括号 tx = DB.Debug().Where("(name like @name OR org_name LIKE @org_name)", sql.Named("name", "%"+cond.Keyword+"%"), sql.Named("org_name", "%"+cond.Keyword+"%")).Where(detail) } else { tx = DB.Debug().Where(detail) } err = tx.Debug().Preload(clause.Associations).Limit(cond.PageSize).Offset(cond.PageAfter).Order(cond.OrderBy + " " + cond.SortBy).Find(&visualizationDatas).Error return visualizationDatas, err }
在两个Where之间加上括号
教训:
在使用 gorm ,同时使用多个 Where
连接条件时,一旦涉及到 or
条件,不能少了括号,否则查询结果会和本意有天差地别。