记一次 Gorm 批量插入遇到的问题以及解决方案
Posted CG国斌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次 Gorm 批量插入遇到的问题以及解决方案相关的知识,希望对你有一定的参考价值。
问题现象
最初,我们用的是老版本的 Gorm,但是因为老版本不支持批量插入的功能,所以我们将 Gorm 做了升级,升级到1.21.9
版本。
- https://github.com/go-gorm/gorm/releases/tag/v1.21.9
升级之后,Gorm 确实支持了批量插入的功能。但因为我们后续用到了批量插入返回的记录ID,也就是数据库自增生成的主键 ID 这个值,这时就出现了问题。当然,出现这个问题是有一个前提的,那就是数据库设置的自增步长大于 1,如果自增步长是 1,则没有问题。
因为数据库主从的问题,我们设置的数据库自增步长是 2,所以我们遇到了这个问题。问题的现象是,我们批量插入了三条记录,数据库自增生成的 ID 分别是 1074、1076 和 1078,但 Gorm 返回的结果中,记录的 ID 分别是 1074、1075 和 1076,这意味着 Gorm 返回的 ID 和数据库自增生成的 ID 不一致。
为了验证这个问题,大家可以通过下面的两条 SQL 查看数据库的自增属性和设置自增步长。
- 查看自增属性:
show variables like '%increment%';
- 设置自增步长:
set @@auto_increment_increment=1;
需要注意的是,上述设置步长命令仅对单次链接有效,重启 mysql 后失效。
解决方案
在出现问题之前,我们用于接收数据库记录的结构为:
type Record struct {
ID int64 `gorm:"primary_key;column:id;type:bigint(20) unsigned;not null" json:"id"`
...
...
CreateTime time.Time `gorm:"column:create_time;type:timestamp;not null" json:"create_time"`
}
在出现问题之后,为了解决这个问题,我们用于接收数据库记录的结构修改为:
type Record struct {
ID int64 `gorm:"primary_key;column:id;type:bigint(20) unsigned;not null;autoIncrementIncrement:2" json:"id"`
...
...
CreateTime time.Time `gorm:"column:create_time;type:timestamp;not null" json:"create_time"`
}
两者的差异就在于后者 ID 的gorm
配置之中,新增了autoIncrementIncrement:2
标签。其中,
autoIncrementIncrement
:表示自动步长,控制连续记录之间的间隔;2
:表示我们数据库设置的自增步长。
实际上,应该是autoIncrementIncrement:N
,其中N
对应我们数据库设置的自增步长,因为我们数据库的自增步长设置是 2,所以这里就配置成了 2,具体可以根据实际情况进行调整。
最后,给大家推荐「Gorm 文档」,没事多看看,可以避免采坑啊!
以上是关于记一次 Gorm 批量插入遇到的问题以及解决方案的主要内容,如果未能解决你的问题,请参考以下文章