问题
在使用 xorm
的过程中,应该大多数人都遇到过更新方面的一些坑,如:在使用结构体映射做更新的时候,无法更新空值。此时,我们可以使用 AllCols
方法来进行强制更新。
最近在使用该方法时,发现值并未进行更改,伪代码如下:
var device model.Device // 需要入库的值
engine.AllCols().Update(&device, &model.Device{Cid: device.Cid, Eid: device.Eid})
需要根据 Cid
和 Eid
来更新 device
表中的信息。但执行完发现,值并未被修改,就很奇怪!!
发现问题
xorm
有 ShowSQL
方法,打印了下 sql
语句,才发现了问题所在。
engine, _ := xorm.NewEngine("sqlite3", "test.db")
engine.ShowSQL()
// 执行语句
engine.ShowSQL(false)
原来 AllCols
方法将我的条件信息也全部都作为 WHERE
条件给解析成 SQL
语句了!!!破案。
解决方法
- 根据主键
Id
来进行更新
engine.Id(xxx).AllCols().Update(&device)
where
条件不要再用原结构体,直接使用map
进行赋值更新
engine.AllCols().Update(&device, map[string]interface{}{"cid": device.Cid, "eid": device.Eid})
总结
xorm
的更新,做成这样,也实属无奈,情有可原。因为在做映射的时候,根本就不可能知道你这个空值到底是要更新的还是就是空值。
在使用方法前,不明确的可以写个小的测试,自己先测试下。
还有,这个 ShowSQL
方法可真是个好东西,可以用其快速定位错误。