背景
Gorm是Go语言使用广泛的ORM框架,在Web项目中一定会存在CRUD功能,最近无意看到 Gorm查询使用Struct实例作为条件,感觉更加优雅。然后将该方法在项目中使用。
// List函数
where := &Product{}
// 发现过滤条件A
where.A = A
// 发现过滤条件A
where.B = B
db.Where(where).Find(&products)
但是这两天测试发现一个问题,就是在调用展示数据列表时,明明加了检索条件,但是却没有生效。开启Gorm SQL日志打印 发现,上述 Struct 条件查询对于字段是零值的情况是不会将其加到where条件中的。
验证
设计一个产品表,包含产品标签,价格和状态。
type Product struct {
gorm.Model
Code string `gorm:"column:code"`
Price uint `gorm:"column:price"`
Status uint `gorm:"status"`
}
在设计的时候将 0 作为某种状态,在检索数据的时候select就会没有status字段的where条件。示例
代码如下
// 3. 查询条件为0的数据
products := &[]Product{}
if err := db.Where("status= ?", "0").Find(&products).Error; err != nil {
log.Fatalf("List product error: %v", err)
}
log.Printf("List product by query: %v", products)
// 4. Struct 条件过滤
products = &[]Product{}
if err := db.Where(&Product{Status: 0}).Find(&products).Error; err != nil {
log.Fatalf("List product error: %v", err)
}
log.Printf("List product by struct: %v", products)
输出结果如下,status的where条件在rows:2中并没有出现
[rows:1] SELECT * FROM `product` WHERE status= '0' AND `product`.`deleted_at` IS NULL
2023/03/23 22:57:06 List product by query: &[{{1 2023-03-23 22:57:06.718 +0800 CST 2023-03-23 22:57:06.718 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}} D42 100 0}
]
[rows:2] SELECT * FROM `product` WHERE `product`.`deleted_at` IS NULL
2023/03/23 22:57:06 List product by struct: &[{{1 2023-03-23 22:57:06.718 +0800 CST 2023-03-23 22:57:06.718 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}} D42 100 0
} {{2 2023-03-23 22:57:06.798 +0800 CST 2023-03-23 22:57:06.798 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}} D42 100 1}]
总结
所以在表字段设计特别是用 int类型 表示 不同状态 时,最好将零值作为 未知状态;或者是在gorm检索时通过Where("status= ?", "0")来添加条件。
本人小白一枚,如有错误敬请指正,不胜感激!