【golang】gorm 中的Where 子句踩坑(实际项目)

简介: 【golang】gorm 中的Where 子句踩坑(实际项目)

一、上案例


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之间加上括号

image.png


教训:


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

目录
相关文章
|
Go 数据库
Golang 语言编写 gRPC 实战项目
Golang 语言编写 gRPC 实战项目
342 0
|
8月前
|
设计模式 Kubernetes Go
​​什么是Golang项目的“主包精简,逻辑外置”?​
“主包精简,逻辑外置”是Go语言项目的一种设计原则,强调将程序入口保持简单,核心逻辑拆分至其他包,以提升代码可维护性、可测试性及扩展性,适用于CLI工具、Web服务等场景。
193 7
|
存储 测试技术 Go
Golang框架实战-KisFlow流式计算框架(2)-项目构建/基础模块-(上)
KisFlow项目源码位于<https://github.com/aceld/kis-flow,初始阶段涉及项目构建和基础模块定义。首先在GitHub创建仓库,克隆到本地。项目目录包括`common/`, `example/`, `function/`, `conn/`, `config/`, `flow/`, 和 `kis/`。`go.mod`用于包管理,`KisLogger`接口定义了日志功能,提供不同级别的日志方法。默认日志对象`kisDefaultLogger`打印到标准输出。
896 84
Golang框架实战-KisFlow流式计算框架(2)-项目构建/基础模块-(上)
|
Go 数据库
golang编程语言操作GORM快速上手篇
使用Go语言的GORM库进行数据库操作的教程,涵盖了GORM的基本概念、基本使用、关联查询以及多对多关系处理等内容。
442 2
|
缓存 NoSQL 中间件
用golang搭建springboot风格项目结构 gin+gorm
最近学了学go语言,想练习一下用go开发web项目,项目结构弄个什么样呢。
|
关系型数据库 MySQL Go
golang使用gorm操作mysql1
golang使用gorm操作mysql1
golang使用gorm操作mysql1
golang使用gorm操作mysql3,数据查询
golang使用gorm操作mysql3,数据查询
|
JSON 前端开发 Java
golang使用gorm操作mysql2
golang使用gorm操作mysql2
|
Go 开发者
Golang深入浅出之-Go语言项目构建工具:Makefile与go build
【4月更文挑战第27天】本文探讨了Go语言项目的构建方法,包括`go build`基本命令行工具和更灵活的`Makefile`自动化脚本。`go build`适合简单项目,能直接编译Go源码,但依赖管理可能混乱。通过设置`GOOS`和`GOARCH`可进行跨平台编译。`Makefile`适用于复杂构建流程,能定义多步骤任务,但编写较复杂。在选择构建方式时,应根据项目需求权衡,从`go build`起步,逐渐过渡到Makefile以实现更高效自动化。
597 2
|
Go
第十二章 Golang家庭收支记账软件项目
第十二章 Golang家庭收支记账软件项目
222 2

推荐镜像

更多