今天在开发项目的时候,在配置统一表前缀的时候,突然发现和之前的配置方式不一样,是因为一个项目使用的是v1.9.6版本,另外一个项目使用的最新1.20.9 也即是作者说的v2.0版本
v1.0 和 v2.0 变化对于使用者来说变化最大的表现在
1、包的安装和import
2、表全局前缀定义和禁用表复数
下面具体来操作验证下不同之处
包的安装和import
v1.0 版本
# http://v1.gorm.io/docs/
go get -u github.com/jinzhu/gorm
# 驱动import如下方式
_ "github.com/jinzhu/gorm/dialects/mysql"
V2.0 版本
# https://gorm.io/docs/
go get -u gorm.io/gorm
# 驱动独立,直接import
go get -u gorm.io/gorm/driver/mysql
数据库连接方式
在介绍表前缀和表复数禁用之前,先说说数据库连接的方式的不同,这个影响到后面有些参数的设置
v1.0版本
dsn := "xxxx:xxxxxx@tcp(127.0.0.1:3306)/yyyyy?charset=utf8mb4&parseTime=True&loc=Local"
// gorm - v1.x
db, err := gorm.Open("mysql", dsn) // *gorm.DB
v2.0版本
dsn := "xxxx:xxxxxx@tcp(127.0.0.1:3306)/yyyyy?charset=utf8mb4&parseTime=True&loc=Local"
// gorm - v2
// gorm.Config 参考 https://gorm.io/docs/gorm_config.html
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
NamingStrategy: schema.NamingStrategy{
TablePrefix: "gormv2_",
SingularTable: true,
Logger: logger.Default.LogMode(logger.Silent),
主要v2.0 Open的参数变化,dsn 是通过独立驱动建立连接,一些全局配置放到了第二个参数 gorm.Config中去,
比如logMode参数定义的变化,具体gorm.Config 参考 https://gorm.io/docs/gorm_config.html
注意,此时两个gorm.Open 返回的db变量 类型都是*gorm.DB
但是 db.DB()
函数返回值却不同:
v1.0 db.DB()
返回一个结果 *sql.DB
v2.0 db.DB()
返回两个结果 *sql.DB
和 error
所以SetMaxIdleConns
、SetMaxOpenConns
和SetConnMaxLifetime
变量的设置就发生了变化
v1.0 可以直接 db.DB().SetMaxIdleConns(10)
v2.0 必须先赋值到新的变量,然后使用新的变量设置
sqlDB, err := db.DB()
if err != nil {
log.Panicln("db.DB() err: ", err)
sqlDB.SetMaxIdleConns(10)
当然还有其他一些细节,等到大家自己深入研究
表前缀和表复数禁用
v1.0 版本
是通过独立的变量来定义
// gorm - v1.x
// 设置全局表名禁用复数
db.SingularTable(true)
// gorm - v1.x
// 指定表前缀,修改默认表名
gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string {
return "gormv1_" + defaultTableName
v2.0 版本
是通过 gorm.Config 来配置
dsn := "xxxx:xxxxxx@tcp(127.0.0.1:3306)/yyyyy?charset=utf8mb4&parseTime=True&loc=Local"
// gorm - v2
// gorm.Config 参考 https://gorm.io/docs/gorm_config.html
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
NamingStrategy: schema.NamingStrategy{
TablePrefix: "gormv2_",
SingularTable: true,
Logger: logger.Default.LogMode(logger.Silent),
直接具体指定表名称
当然对于Model对应的数据库表名称还有一种共同的定义方式,如下
func (ModelName) TableName() string {
return "self-define-tablename"
这里定义的表名称不依赖上面介绍的表前缀和禁用表复数
演示是分两个主文件,执行一个的时候,记得把另外一个改名备份即可
v1.0 方式执行结果
mysql> desc gormv1_todo ;
+--------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| created_at | datetime | YES | | NULL | |
| updated_at | datetime | YES | | NULL | |
| deleted_at | datetime | YES | MUL | NULL | |
| title | varchar(255) | YES | | NULL | |
| is_completed | tinyint(1) | YES | | NULL | |
+--------------+------------------+------+-----+---------+----------------+
6 rows in set (0.01 sec)
v2.0 方式执行结果
mysql> desc gormv2_todo ;
+--------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| created_at | datetime(3) | YES | | NULL | |
| updated_at | datetime(3) | YES | | NULL | |
| deleted_at | datetime(3) | YES | MUL | NULL | |
| title | longtext | YES | | NULL | |
| is_completed | tinyint(1) | YES | | NULL | |
+--------------+---------------------+------+-----+---------+----------------+
6 rows in set (0.01 sec)
mysql> desc mytag ;
+------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| created_at | datetime(3) | YES | | NULL | |
| updated_at | datetime(3) | YES | | NULL | |
| deleted_at | datetime(3) | YES | MUL | NULL | |
| name | longtext | YES | | NULL | |