0%

GORM升级V2过程中的注意事项

最近逐渐把手中负责的几个golang项目中的gorm升级到v2版本。之前看v2的升级说明并没有什么大的感觉,但真要升级的时候发现其中还真有好多需要注意的点,不然很容易就踩坑了。

项目中使用的是 mysql 数据库。

使用 gorm v2

这个不必多说,直接执行如下命令即可。替换掉之前的引用:

1
2
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql

int类型

golang中的 Model,对于某些小数据量的字段,例如 genderstatus 等,我一般使用 int8int 类型来定义,对应于mysql中的 tinyintint 类型。

而对于大数据量的字段,例如 主键IdCreateTime 等,则一般使用 int64 来定义,对应于mysql中的 bigint 类型。

gorm v1 版本中,如果不特意指定说明,则 int 会映射为 int(11) 类型,int64 会映射为 bigint(20) 类型。

但在 gorm v2 版本中,如果没有特意指定,则 intint64 都会默认映射为 bigint(20) 类型。

1
2
3
4
type Student struct{
Id int64 `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
Status int `json:"status" gorm:"column:status;not null;default:0"`
}

gorm v2 中,如果想要映射成 int(11) 类型,则需要指定使用的 type :

1
2
3
4
type Student struct{
Id int64 `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
Status int `json:"status" gorm:"column:status;type:int(11);not null;default:0"`
}

主键自增

gorm v2 的升级说明文档中,标明在新版本中需要使用 camelCase 风格的语法来定义标签。例如要使用 autoIncrement 标签来说明该字段是 自增 的。

但我在使用时却发现这其中还是需要注意的。如下的写法:

1
Id       int64  `json:"id" gorm:"column:id;type:bigint(20);primaryKey;autoIncrement"`

结果插入数据时报错: Error 1364: Field 'id' doesn't have a default value

结合上面第一个问题,我使用了 type:bigint(20); 来标明映射到mysql时使用的数据类型。结果执行时发现 自增 设置并没有生效。

将其改成如下写法后,经测试成功:

1
Id       int64  `json:"id" gorm:"column:id;primaryKey;AUTO_INCREMENT"`

为了探究到底是哪里的问题,我做了如下的测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type API struct {
Id int64 `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"` // 主键自增 成功
Id int64 `json:"id" gorm:"column:id;primaryKey;AUTO_INCREMENT"` // 主键自增 成功
Id int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 主键自增 成功
Id int64 `json:"id" gorm:"column:id;primary_key;autoIncrement"` // 主键自增 成功

Id int64 `json:"id" gorm:"column:id;type:bigint(20);primaryKey;auto_increment"` // 主键不自增 失败
Id int64 `json:"id" gorm:"column:id;type:bigint(20);primaryKey;autoIncrement"` // 主键不自增 失败
Id int64 `json:"id" gorm:"column:id;type:bigint(20);primaryKey;AUTO_INCREMENT"` // 主键不自增 失败

Id int64 `json:"id" gorm:"column:id;type:bigint(20) auto_increment;primary_key"` // 主键自增 成功
Id int64 `json:"id" gorm:"column:id;type:bigint(20) autoIncrement;primaryKey"` // Error 1064: You have an error in your SQL syntax;
Id int64 `json:"id" gorm:"column:id;type:bigint(20) AUTO_INCREMENT;primaryKey"` // 主键自增 成功

Id int64 `json:"id" gorm:"column:id;primaryKey;type:bigint(20) autoIncrement;"` // Error 1064: You have an error in your SQL syntax;
Id int64 `json:"id" gorm:"column:id;primaryKey;type:bigint(20) auto_increment;"` // 主键自增 成功
Id int64 `json:"id" gorm:"column:id;type:bigint(20) auto_increment;primaryKey"` // 主键自增 成功
}

个中滋味,大家还是自己体会吧!!!

至于怎么用,那就总结一下:

如果你不需要指定类型,则:

1
Id      int64  `json:"id" gorm:"column:id;primaryKey;AUTO_INCREMENT"`

如果你想要指定类型,则:

1
Id           int64  `json:"id" gorm:"column:id;type:bigint(20) auto_increment;primaryKey"`

comment说明

gorm v1 中,为字段添加说明信息时,需要用 引号包裹 内容: comment:'创建时间' ;而升级到 gorm v2 后,不需要 引号 了:comment:创建时间

看如下的对比:

1
2
3
4
5
// gorm v1
CreateTime int64 `json:"create_time" gorm:"column:create_time;comment:'创建时间'"`

// gorm v2
CreateTime int64 `json:"create_time" gorm:"column:create_time;comment:创建时间"`

如有疑问或需要技术讨论,请留言或发邮件到 service@itfanr.cc