目录

go gorm 判断 db 对象是否存在 where 条件

一、问题

最近有个极端、特殊的需求场景,在使用 gorm 操作数据库时,想着能不能判断一下 gorm db 对象是否已经存在 where 条件,如果存在 where 条件则执行特殊逻辑

但是通过阅读官方 gorm 文档,发现官方并没有提供类似的方法和 API,无奈+好奇之下,想着要不然翻翻看 gorm 的源码,看看能不能解决这个特殊需求

ps:这个需求场景比较特殊,不常见,本文作者纯粹是处于好奇研究,最终并没有使用研究后的方法实现,因此结论仅供参考

二、解决

通过阅读 gorm 的源码,可以发现 db 对象中有个Statement 对象,该对象中有个 Clauses 对象,在使用 where、order、or 方法时会存储结果到 Clauses 对象中

  • db.Statement.Clauses

那我们是不是可以通过判断 len(db.Statement.Clauses) 的长度来判断当前 db 对象是否存在 where 条件呢?

写一段测试代码来验证下想法,代码如下:

创建 gorm db 链接

// 创建gorm句柄 
 dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
 db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

在使用 where 条件之前,我们先打印下 db.Statement.Clauses 或者 db.Clauses 的长度

 fmt.Println("db.Statement.Clauses len:", len(db.Statement.Clauses))

输出结果:

db.Statement.Clauses len:0

添加 where 条件,并且再次打印 db.Statement.Clauses 的长度

db = db.Where("name=?", "fiveyoboy")
fmt.Println("db.Statement.Clauses len:", len(db.Statement.Clauses))

输出结果:

db.Statement.Clauses len:1

这里我们再添加几个 where 条件,加强一下验证

db = db.Where("name1=?", "fiveyoboy")
db = db.Where("name2=?", "fiveyoboy")
db = db.Where("name3=?", "fiveyoboy")
fmt.Println("db.Statement.Clauses len:", len(db.Statement.Clauses))

输出结果:

db.Statement.Clauses len:4

从上面的输出结果可以明显看出有一个 4 个where,因此我们基本可以确定是可以通过 len(db.Statement.Clauses) 来判断where条件是否存在的

总结

通过以上的分析研究,我们基本可以得出结论:go gorm 可以通过 len(db.Statement.Clauses) > 0 来判断当前 db 对象是否存在 where 条件

通过源码解读可以发现,在使用 db.where()、db.order()、db.or() 等方法添加过滤条件时,gorm 内部是将这些条件解析后存储在 db.Statement.Clauses 对象中,最终解析成 sql 语句

当然这种方式是否足够健壮还有待验证,在某些特殊场景下还是可以使用的….

除了这个方法之外,你们还有其他什么方法可以实现类似的效果吗?👏👏👏欢迎大家在评论区交流沟通

版权声明

未经授权,禁止转载本文章。
如需转载请保留原文链接并注明出处。即视为默认获得授权。
未保留原文链接未注明出处或删除链接将视为侵权,必追究法律责任!

本文原文链接: https://fiveyoboy.com/articles/go-gorm-where-len/

备用原文链接: https://blog.fiveyoboy.com/articles/go-gorm-where-len/