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

2023-03-05  本文已影响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 子句的本意转换成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

解决办法:

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
}

教训:

在使用 gorm ,同时使用多个 Where 连接条件时,一旦涉及到 or 条件,不能少了括号,否则查询结果会和本意有天差地别。

上一篇 下一篇

猜你喜欢

热点阅读