当前位置: 首页 > news >正文

gorm使用Session()函数后where条件不生效

问题描述

下面query2的Where条件在查询时不会生效

func main() {var data map[string]anyDB := simdb.InitGormMysql(dbConfig)//gorm初始化函数,请忽略query1 := DB.Model(&User{})query2 := query1.Session(&gorm.Session{})query2.Where("id =100")query2.Debug().Find(&data)
}

调试信息如下,可以看到query2的where条件没有加上

[11.136ms] [rows:1] SELECT * FROM `sys_user`

正确写法:

通过修改Session配置可以让query2的where直接生效

query2 := query1.Session(&gorm.Session{Initialized: true, //让Initialized为true即可})
query2.Where('id =1')
query2.Where("name='张三'")

另一种,每次使用where函数,都接收一次它的返回值。

query2:=query1.Session(&gorm.Session{})
query2=query2.Where('id =1')
query2=query2.Where("name='张三'")

有人也喜欢这么写,建立新的查询时,用一次where条件,后面就不用每次都赋值了。

query2:= query1.Session(&gorm.Session{}).Where('id =1')
//下面不用每次都赋值了
query2.Where("name='张三'")
query2.Where("name='李四'")

上面两种写法,第一种更加规范,可以减少bug的出现频率。第二种,代码是变简单了,但是非常容易遗漏。

问题原因

看一下调用 Session函数 时的执行过程

func (db *DB) Session(config *Session) *DB {var (txConfig = *db.Config // 注意点1: 注意这里初始化了一个新的txConfigtx       = &DB{Config:    &txConfig,Statement: db.Statement,Error:     db.Error,clone:     1,})//...省略部分代码//...//...//这里如果是false,不会生成新的实例。if config.Initialized { tx = tx.getInstance()}return tx
}

再来看where函数的代码:

func (db *DB) Where(query interface{}, args ...interface{}) (tx *DB) {// 这里生成了新的实例tx,而不是在原先的db基础上修改的tx = db.getInstance()if conds := tx.Statement.BuildCondition(query, args...); len(conds) > 0 {tx.Statement.AddClause(clause.Where{Exprs: conds})}return
}

首先通过Session和Where函数的代码对比,就知道该,把配置Session的Initialized设置为true,就能让where条件生效了(更深的细节文字不好描述,就不讲了):

func main() {var data map[string]anyDB := simdb.InitGormMysql(dbConfig)query1 := DB.Model(&User{})query2 := query1.Session(&gorm.Session{Initialized: true, //让Initialized为true即可})query2.Where("id =100")query2.Debug().Find(&data)
}

再看下官方文档,是这么写的:
在这里插入图片描述

根据官方示例,结合Session和Where函数的代码对比。我觉得开发者可能最初目的是为了减少db.getInstance()函数的调用。。。

  • 官方的这种查询方式,tx.getInstance()只会在Where中触发,总共触发了一次,

    queryDB := DB.Where( "name = ?" , "jinzhu" ).Session(&gorm.Session{})
    queryDB.Where( "age > !" , 10 ).First(&user) 
    
  • 官方的这种查询方式,tx.getInstance()在Session和Where中都执行了,总共触发了两次,效率变差了…

    queryDB := DB.Where( "name = ?" , "jinzhu" ).Session(&gorm.Session{Initialized: true})
    queryDB.Where( "age > !" , 10 ).First(&user) 
    

但是这么设计,真的非常不友好…


http://www.mrgr.cn/news/82983.html

相关文章:

  • UI自动化测试保姆级教程--pytest详解(精简易懂)
  • UE 5.3 C++ 管理POI 如何对WidgetComponent 屏幕模式进行点击
  • 海陵HLK-TX510人脸识别模块 stm32使用
  • Excel中公式和函数的区别
  • krpano 实现文字热点中的三角形和竖杆
  • UE5 打包要点
  • matlab系列专栏-快捷键速查手册
  • 为什么页面无法正确显示?都有哪些HTML和CSS相关问题?
  • uniapp打包到宝塔并发布
  • OSPF浅析
  • 使用 uniapp 开发微信小程序遇到的坑
  • 关于ssh-server在windows系统中进行部署及通过mobaxterm中ssh隧道技术实现不同网段之间进行网络通讯的问题
  • Mycat2使用教程
  • Three.js 基础概念:构建3D世界的核心要素
  • Win10本地部署大语言模型ChatGLM2-6B
  • MySql 通过 LOAD DATA INFILE 导入大量数据
  • [文献精汇]使用PyCaret预测 Apple 股价
  • 【简博士统计学习方法】第1章:1. 统计学习的定义与分类
  • 概率论 期末 笔记
  • 力扣刷题常用API总结 (1):字符串,字符数组
  • 【简博士统计学习方法】第1章:3. 统计学习方法的三要素
  • 【简博士统计学习方法】第1章:4. 模型的评估与选择
  • SAP 采购-生产-销售-月结 流程
  • halcon三维点云数据处理(七)find_shape_model_3d_recompute_score
  • 【CPU】页,帧,页表,页表项,三级页表
  • 前端开发 vue 中如何实现 u-form 多个form表单同时校验