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/