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,对于某些小数据量的字段,例如 gender 、status 等,我一般使用 int8 或 int 类型来定义,对应于mysql中的 tinyint 、int 类型。

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

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

但在 gorm v2 版本中,如果没有特意指定,则 int 和 int64 都会默认映射为 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