文章目录
- 引入依赖
- 读取配置文件
- 配置数据库连接池
- 定义模型
- 数据库表信息
- 创建对应结构体
- 数据模型中字段的标签属性
- column
- serializer
- primaryKey
- default
- autoIncrement / AUTO_INCREMENT
- embedded / embeddedPrefix
- autoCreateTime
- autoUpdateTime
- -
- foreignKey / references
引入依赖
go get -u github.com/spf13/viper
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
读取配置文件
配置文件结构如下:
设置了数据库连接信息、最大连接数、最大空闲数这三个配置 。
package config
import (
"github.com/spf13/viper"
)
var AppConfig *Config
type Config struct {
Mysql MysqlConfig `json:"mysql"`
}
/*
* Mysql 相关配置
*/
type MysqlConfig struct {
Dsn string `json:"Dsn"`
MaxIdleConns *int `json:"MaxIdleConns,omitempty"`
MaxOpenConns *int `json:"MaxOpenConns,omitempty"`
}
func LoadConfig() error {
viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AddConfigPath("./config")
//读取配置文件
if err := viper.ReadInConfig(); err != nil {
return err
}
//将配置文件中的信息读取到结构体中
if err := viper.Unmarshal(&AppConfig); err != nil {
return err
}
return nil
}
func GetAppConfig() Config {
return *AppConfig
}
配置数据库连接池
- 使用连接池,避免频繁创建数据库链接
- 控制最大连接数和最大空闲数
- Gorm 默认使用表名复数形式,即若使用 User 结构体,默认对应的表名是 users ,需要配置表名不使用复数形式
package cus_orm
import (
"mingvvv/config"
"gorm.io/driver/mysql"
"gorm.io/gorm/schema"
"gorm.io/gorm"
)
var db *gorm.DB
func MysqlConnection() *gorm.DB {
if db == nil {
config := config.GetAppConfig()
dsn := &config.Mysql.Dsn
maxIdleConns := config.Mysql.MaxIdleConns
maxOpenConns := config.Mysql.MaxOpenConns
if dsn == nil {
panic("non mysql dsn")
}
dbcreater, err := gorm.Open(mysql.Open(*dsn), &gorm.Config{
NamingStrategy: schema.NamingStrategy{
SingularTable: true, //表名不使用复数形式
},
})
db = dbcreater
if err != nil {
panic("failed to connect database")
}
sqlDb, _ := db.DB()
if maxIdleConns != nil {
sqlDb.SetMaxIdleConns(*maxIdleConns) // 设置最大空闲数
}
if maxOpenConns != nil {
sqlDb.SetMaxOpenConns(*maxOpenConns) // 设置最大连接数
}
}
return db
}
定义模型
数据库表信息
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '姓名',
`infant_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '小名',
`age` int DEFAULT NULL COMMENT '年龄',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
`user_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '描述',
`json_field` json DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=534 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE `user_role` (
`id` int NOT NULL AUTO_INCREMENT,
`user_id` int DEFAULT NULL COMMENT '用户ID',
`role_id` int DEFAULT NULL COMMENT '角色ID\r\n',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=531 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
创建对应结构体
type User struct {
Id uint `json:"id" gorm:"primary_key;AUTO_INCREMENT"`
Name string `gorm:"column:name"`
InfantName string
Age int `gorm:"default:18"`
UserDesc string
JsonField map[string]string `gorm:"serializer:json"`
CreateTime time.Time
UpdateTime time.Time
UserRole UserRole `gorm:"foreignKey:UserId;references:Id"` //指定外键
}
type UserRole struct {
Id uint `json:"id" gorm:"primary_key;AUTO_INCREMENT"`
UserId uint
RoleId uint
}
数据模型中字段的标签属性
如上,我们在创建数据模型的时候在字段后面增加一系列 gorm 标签,这些标签将会影响字段在读写时的功能表现。
下面是几种比较常用的标签属性,其余的可以参考官网链接
https://gorm.io/docs/models.html#embedded_struct
column
用来指定结构体中字段对应数据库中哪个字段
例如结构体 User 中指定 Name 对应数据库表中的 name 字段
serializer
指定字段的序列化方式
例如在结构体 User 中有这样一行
JsonField map[string]string `gorm:"serializer:json"`
表示将结构体中的字典和数据库中的 json 类型做序列化转换。
如果不做序列化,那么我们在新增或读取数据时会爆出异常:
//新增时
[error] unsupported data type: &map[]
primaryKey
指定字段为主键
default
指定字段的默认值
autoIncrement / AUTO_INCREMENT
指定字段为自增
需要注意的是,如果字段设置了 type 标签,autoIncrement 标签要紧跟在 type 标签后设置,否则可能会不生效
例如gorm:"type:bigint autoIncrement"
embedded / embeddedPrefix
embedded 将结构体中的字段嵌入到当前结构体中 ,embeddedPrefix 在属性前添加前缀
type Desc struct {
Desc1 string
Desc2 string
}
type User struct {
Id uint `json:"id" gorm:"primary_key;AUTO_INCREMENT"`
Name string `gorm:"column:name"`
InfantName string
Age int `gorm:"default:18"`
Desc Desc `gorm:"embedded;embeddedPrefix:user_"`
}
其中结构体 User 等价于下面的结构体
type User struct {
Id uint `json:"id" gorm:"primary_key;AUTO_INCREMENT"`
Name string `gorm:"column:name"`
InfantName string
Age int `gorm:"default:18"`
Desc1 string `gorm:"column:user_desc1"`
Desc2 string `gorm:"column:user_desc2"`
}
autoCreateTime
在创建时自动填充当前时间,当字段属性是 int 类型时,将获取当前时间的 unix 时间戳
autoCreateTime:nano
微秒
autoCreateTime:milli
毫秒
autoUpdateTime
在创建或者修改时自动填充当前时间,当字段属性是 int 类型时,将获取当前时间的 unix 时间戳
autoCreateTime:nano
微秒
autoCreateTime:milli
毫秒
-
忽略当前字段
foreignKey / references
设置外键关联
在结构体 User 中的这一行
UserRole UserRole `gorm:"foreignKey:UserId;references:Id"`
表示:
user_role 的外键是 user_id,对应 user 表的 id 字段。
从结构体关系上来看就是,UserRole 结构体通过 UserId 和 User 结构体的 Id 进行关联。
这种关系会在新增数据时触发关联插入的操作
即,如果插入一条user数据,且结构体中 UserRole 不为零值,那么他也会同时向 user_role 表中插入一条数据,而且会自动填充外键值(user表的Id)