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

目录
相关文章
|
11月前
|
Go 数据库
Golang 语言编写 gRPC 实战项目
Golang 语言编写 gRPC 实战项目
117 0
|
25天前
|
Go 数据库
golang编程语言操作GORM快速上手篇
使用Go语言的GORM库进行数据库操作的教程,涵盖了GORM的基本概念、基本使用、关联查询以及多对多关系处理等内容。
27 1
|
4月前
|
存储 测试技术 Go
Golang框架实战-KisFlow流式计算框架(2)-项目构建/基础模块-(上)
KisFlow项目源码位于<https://github.com/aceld/kis-flow,初始阶段涉及项目构建和基础模块定义。首先在GitHub创建仓库,克隆到本地。项目目录包括`common/`, `example/`, `function/`, `conn/`, `config/`, `flow/`, 和 `kis/`。`go.mod`用于包管理,`KisLogger`接口定义了日志功能,提供不同级别的日志方法。默认日志对象`kisDefaultLogger`打印到标准输出。
653 6
Golang框架实战-KisFlow流式计算框架(2)-项目构建/基础模块-(上)
|
4月前
|
关系型数据库 MySQL Go
golang使用gorm操作mysql1
golang使用gorm操作mysql1
golang使用gorm操作mysql1
|
4月前
|
Go
golang使用gorm操作mysql3,数据查询
golang使用gorm操作mysql3,数据查询
|
4月前
|
JSON 前端开发 Java
golang使用gorm操作mysql2
golang使用gorm操作mysql2
|
4月前
|
Go 开发者
Golang深入浅出之-Go语言项目构建工具:Makefile与go build
【4月更文挑战第27天】本文探讨了Go语言项目的构建方法,包括`go build`基本命令行工具和更灵活的`Makefile`自动化脚本。`go build`适合简单项目,能直接编译Go源码,但依赖管理可能混乱。通过设置`GOOS`和`GOARCH`可进行跨平台编译。`Makefile`适用于复杂构建流程,能定义多步骤任务,但编写较复杂。在选择构建方式时,应根据项目需求权衡,从`go build`起步,逐渐过渡到Makefile以实现更高效自动化。
73 2
|
4月前
|
Go
golang学习3,golang 项目中配置gin的web框架
golang学习3,golang 项目中配置gin的web框架
|
4月前
|
Go
第十二章 Golang家庭收支记账软件项目
第十二章 Golang家庭收支记账软件项目
77 2
|
4月前
|
缓存 Cloud Native 测试技术
Golang 乐观锁实战:Gorm 乐观锁的优雅使用
在现代软件开发中,数据一致性是一个永恒的话题。随着系统规模的扩大和并发操作的增加,如何有效地处理并发冲突,确保数据的完整性,成为了开发者必须面对的挑战。本文将带你深入了解 Golang 中 Gorm ORM 库的乐观锁机制,并通过实际示例,展示如何在项目中优雅地使用乐观锁。