gorm v2 AutoMigrate神奇的操作

3,087 阅读2分钟

今天学习gorm的使用,照着官方文档简单了写了个连接+建表,代码如下:

package main

import (
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

const dsn = "你的Mysql连接串"

type Person struct {
	Id   string
	Name string
	Age  int32
}

func main() {
	db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})

	_ = db.AutoMigrate(&Person{})

}

结果神奇的事情出来了,我的Person本应该是创建成persons,它给我整了个people出来。给我打了一个措手不及。

我连忙创建了一个新的结构体做实验

package main

import (
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

const dsn = "你的Mysql连接串"

type User struct {
	Id       int64
	IdNumber string
}

func main() {
	db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	_ = db.AutoMigrate(&User{})
}

这下我的users创建成功了,于是我明白一定是我的person名字出了问题。

通过查询文档发现,在gorm.Config{}里面有一个配置叫NamingStrategy,感觉应该和这个配置有关系,通过对这个参数if的判断找到用它的地方,有一个TableName方法引起了我的注意

终于,在inflection.Plural下找到了personpeople的秘密

原来gorm默认的复数形式不是简单的加s或es,是根据其词的意义来加的,对特殊的词进行了特殊处理。通过阅读代码,发现有几个词是不会变形的

由此gorm AutoMigrate命名的神奇操作就分析完了。

另外作为一个Java程序员,在我的编程规范里面,表名应该是单数而不是复数。名字代表其数据的性质(名称),而其里面的内容注定是不只有一条(不然也不用mysql了对吧)。所以没必要整个加长,增加存储负担(多打几个无意义的字母,你多1我多1,整个世界的网络会被浪费多少流量,硬盘会被浪费多少存储空间啊)。

所以需要一个关闭它的方法,在v1的gorm中,关闭表名复数很简单

db.SingularTable(true)

而在v2的gorm中,稍微复杂一点,需要我们上面的老朋友 NamingStategy

	db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{
		NamingStrategy: schema.NamingStrategy{
			SingularTable: true,
		},
	})

说完了,再见