美文网首页
600. 【golang】gorm 中的Where 子句踩坑(实

600. 【golang】gorm 中的Where 子句踩坑(实

作者: 七镜 | 来源:发表于2023-03-05 14:26 被阅读0次

一、上案例

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 条件,不能少了括号,否则查询结果会和本意有天差地别。

相关文章

网友评论

      本文标题:600. 【golang】gorm 中的Where 子句踩坑(实

      本文链接:https://www.haomeiwen.com/subject/kdnuldtx.html