阅读目录
- 模型定义
- 1 模型定义商品表
- 2 模型标签
- 3 表名映射
- 4 Model
- 5. 数据库连接
- 5.1 DSN
- 5.2 连接数据库
- 5.3 调试模式
- 5.4 连接池配置
模型定义
前面入门案例中,我们定义了 User
结构体用来和数据表 users
做映射,User 结构体,我们称之为数据模型,在 gorm
框架中,操作数据库需要预先定义模型。
底层都是使用的 golang 的 database 标准库,利用反射原理,执行读写操作时,将结构体翻译为 sql
语句,并将结果转化为对应的模型。
1 模型定义商品表
CREATE TABLE `goods` (`id` INT (10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增ID,商品Id',`name` VARCHAR (30) NOT NULL COMMENT '商品名',`price` DECIMAL (10, 2) UNSIGNED NOT NULL COMMENT '商品价格',`type_id` INT (10) UNSIGNED NOT NULL COMMENT '商品类型Id',`createtime` INT (10) NOT NULL DEFAULT 0 COMMENT '创建时间',PRIMARY KEY (`id`)
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4
将上述表翻译为模型后,如下:
type Good struct {Id int Name string Price float64 TypeId int CreateTime int64 `gorm:"column:createtime"`
}
默认 gorm 对 struct 字段名使用 Snake Case 命名风格转换成 mysql 表字段名(需要转换成小写字母)。
Snake Case 命名风格,就是各个单词之间用下划线(_)分隔,例如: CreateTime的Snake Case风格命名为 create_time。
同时默认情况下,使用 ID
做为其主键,使用结构体名称的 Snake Case 风格的复数形式做为表名,使用 CreatedAt、UpdatedAt 字段追踪创建、更新时间。
2 模型标签
标签定义:
`gorm:"标签内容"`
标签定义部分,多个标签定义可以使用分号(;
)分隔。
gorm 常用标签如下:
标签 | 说明 | 例子 |
---|
column | 指定列名 | gorm:"column:createtime" |
primaryKey | 指定主键 | gorm:"column:id; PRIMARY_KEY" |
- | 忽略字段 | gorm:"-" 可以忽略 struct 字段,被忽略的字段不参与 gorm 的读写操作。 |
3 表名映射
复数表名,比如结构体 User
,默认的表名为 users
。会缓存表名。
实现 Tabler 接口 (TableName 不支持动态变化,它会被缓存下来以便后续使用。)
type Tabler interface {TableName() string
}
func (User) TableName() string {return "profiles"
}
动态表名,使用 Scopes。
func UserTable(user User) func (tx *gorm.DB) *gorm.DB {return func (tx *gorm.DB) *gorm.DB {if user.Admin {return tx.Table("admin_users")}return tx.Table("users")}
}db.Scopes(UserTable(user)).Create(&user)
临时表名
db.Table("deleted_users")
默认方式 - 推荐
type User struct {ID int64 Username string `gorm:"column:username"`Password string `gorm:"column:password"`CreateTime int64 `gorm:"column:createtime"`
}
func (u User) TableName() string {return "users"
}
4 Model
GORM 定义一个 gorm.Model
结构体,其包括字段 ID、CreatedAt、UpdatedAt、DeletedAt
。
type Model struct {ID uint `gorm:"primaryKey"`CreatedAt time.TimeUpdatedAt time.TimeDeletedAt gorm.DeletedAt `gorm:"index"`
}
GORM 约定使用 CreatedAt、UpdatedAt
追踪创建/
更新时间。如果定义了这种字段,GORM 在创建、更新时会自动填充当前时间。
要使用不同名称的字段,您可以配置 autoCreateTime、autoUpdateTime
标签。
如果想要保存 UNIX(毫/纳)秒时间戳,而不是 time
,只需简单地将 time.Time
修改为 int
即可。
例子:
type User struct {CreatedAt time.Time UpdatedAt int Updated int64 `gorm:"autoUpdateTime:nano"` Updated int64 `gorm:"autoUpdateTime:milli"` Created int64 `gorm:"autoCreateTime"`
}
可以将它嵌入到您的结构体中,以包含这几个字段,比如:
type User struct {gorm.ModelName string
}
type User struct {ID uint `gorm:"primaryKey"`CreatedAt time.TimeUpdatedAt time.TimeDeletedAt gorm.DeletedAt `gorm:"index"`Name string
}
对于正常的结构体字段,你也可以通过标签 embedded
将其嵌入,例如:
type Author struct {Name stringEmail string
}type Blog struct {ID intAuthor Author `gorm:"embedded"`Upvotes int32
}
type Blog struct {ID int64Name stringEmail stringUpvotes int32
}
可以使用标签 embeddedPrefix
来为 db
中的字段名添加前缀,例如:
type Blog struct {ID intAuthor Author `gorm:"embedded;embeddedPrefix:author_"`Upvotes int32
}
type Blog struct {ID int64AuthorName stringAuthorEmail stringUpvotes int32
}
5. 数据库连接
GORM 官方支持的数据库类型有:
- MySQL
- PostgreSQL
- SQlite
- SQL Server
连接数据库主要是两个步骤:
1、配置 DSN (Data Source Name)。
2、使用 gorm.Open
连接数据库。
5.1 DSN
gorm 库使用 dsn
作为连接数据库的参数,dsn
翻译过来就叫数据源名称,用来描述数据库连接信息。一般都包含数据库连接地址,账号,密码之类的信息。
格式:
[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...¶mN=valueN]
mysql 的 dsn 的一些例子:
username:password@tcp(host:port)/Dbname?charset=utf8&parseTime=True&loc=Local
root:123456@tcp(localhost:3306)/gorm?charset=utf8&parseTime=True&loc=Local
root:123456@tcp(localhost:3306)/gorm?charset=utf8&parseTime=True&loc=Local&timeout=10s
root:123456@tcp(localhost:3306)/gorm?charset=utf8&parseTime=True&loc=Local&timeout=10s&readTimeout=30s&writeTimeout=60s
要支持完整的 UTF-8 编码,您需要将 charset=utf8 更改为 charset=utf8mb4。
5.2 连接数据库
import ("gorm.io/driver/mysql""gorm.io/gorm"
)func main() {dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
}
MySQL 驱动程序提供了 一些 高级配置 可以在初始化过程中使用,例如:
db, err := gorm.Open(mysql.New(mysql.Config{DSN: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8&parseTime=True&loc=Local", DefaultStringSize: 256, DisableDatetimePrecision: true,DontSupportRenameIndex: true, DontSupportRenameColumn: true, SkipInitializeWithVersion: false,
}), &gorm.Config{})
GORM 允许通过 DriverName 选项自定义 MySQL 驱动,例如:
import (_ "example.com/my_mysql_driver""gorm.io/driver/mysql""gorm.io/gorm"
)db, err := gorm.Open(mysql.New(mysql.Config{DriverName: "my_mysql_driver",DSN: "gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True&loc=Local",
}), &gorm.Config{})
5.3 调试模式
db.Debug()
5.4 连接池配置
sqlDB, _ := db.DB()
sqlDB.SetMaxOpenConns(100)
sqlDB.SetMaxIdleConns(20)