GORM 概述
GORM 是面向 Golang 语言的一种 ORM (持久层)框架,支持多种数据库的接入,例如MySQL、PostgreSQL、SQLite、SQL Server、Clickhouse。该框架弱化了开发者对于SQL语言的掌握程度,使用提供的API进行底层数据库的访问。
特点:
- 全功能ORM
- 关联(包含一个,包含多个,属于,多对多,多种包含)
- Callbacks(创建/保存/更新/删除/查找之前/之后)
- 预加载
- 事务
- 复合主键
- SQL Builder
- 自动迁移
- 日志
- 可扩展,编写基于GORM回调的插件
- 每个功能都有测试
- 对开发人员友好
快速开始
安装与连接
go get -u gorm.io/gorm
注:这里要确保自己的项目生成成功,含有正确的go.mod文件
连接MySQL数据库
package main
import (
"fmt"
"time"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
func main() {
dsn := "root:123456@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
//数据库连接池
sqlDB, err := db.DB()
// SetMaxIdleConns 设置空闲连接池中连接的最大数量
sqlDB.SetMaxIdleConns(10)
// SetMaxOpenConns 设置打开数据库连接的最大数量。
sqlDB.SetMaxOpenConns(100)
// SetConnMaxLifetime 设置了连接可复用的最大时间。
sqlDB.SetConnMaxLifetime(time.Hour)
fmt.Println("success to link mysql")
}
此时控制台输出:
PS F:\work\Go\golangStudy> go run gorm.go
success to link mysql
对表数据进行增删改查
增加一个User的结构体与表进行映射
type User struct {
Id int
Name string
Age int
}
实现增删改查
// 自动迁移
db.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(&User{})
// 增
db.Create(&User{
Name: "张三",
Age: 18,
})
// 查
var user User
db.First(&user)
fmt.Println(user) // {1 张三 18}
// 改
user.Name = "李四"
db.Save(&user)
fmt.Println(user) // {1 李四 18}
// 删
db.Delete(&user)
此时控制台输出
PS F:\work\Go\golangStudy> go run gorm.go
success to link mysql
2023/08/24 21:20:24 F:/work/Go/golangStudy/gorm.go:35 SLOW SQL >= 200ms
[1130.857ms] [rows:0] CREATE TABLE `users` (`id` bigint AUTO_INCREMENT,`name` longtext,`age` bigint,PRIMARY KEY (`id`))ENGINE=InnoDB
{1 张三 18}
{1 李四 18}
上述事例中我们使用 Set 方法设置了表选项,然后调用 AutoMigrate 方法来自动迁移 User 模型对应的表结构
模型定义
模型名和表名的映射关系:
- 第一个大写字母变为小写
- 遇到其他大写字母变为小写并且在前面加下划线
- 连着的几个大写字母,只有第一个遵循上面的两条规则,其他的大写字母转为小写,不加下划线,遇到小写,前面的第一个大写字母变小写并加下划线
- 复数形式
结构体字段名和列名的对应规则 列名是字段名的蛇形小写
gorm.Model 基本模型定义gorm.Model,包括字段:
- ID:主键自增长
- CreatedAt:用于存储记录的创建时间
- UpdatedAt:用于存储记录的修改时间
- DeletedAt:用于存储记录的删除时间
使用方式: 只需要在自己的模型中制定gorm.Model的匿名字段
gorm.Model.go
package gorm
import "time"
type Model struct {
ID uint `gorm:"primarykey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt DeletedAt `gorm:"index"`
}
// 添加字段 `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`
type User struct {
gorm.Model
Name string
}
字段标签
声明 model 时,tag 是可选的,GORM 支持以下 tag: tag 名大小写不敏感,多个属性值之间用分号分隔(英文的;):gorm:"size:64;not null"
| 标签名 | 说明 |
|---|---|
| column | 指定 db 列名 |
| type | 列数据类型,推荐使用兼容性好的通用类型,例如:所有数据库都支持 bool、int、unit、float、string、time、bytes 并且可以和其他标签一起使用,例如:not null、size、autoIncrement...像 varbinary(8)这样指定数据库数据类型也是支持的。在使用指定数据库数据类型时,它需要是完整的数据库数据类型,如:MEDIUMINT UNSIGNED not NULL AUTO_INSTERMENT |
| size | 指定列大小,例如:size:256 |
| primaryKey | 指定列为主键 |
| unique | 指定列为唯一 |
| default | 指定列的默认值 |
| precision | 指定列的精度 |
| scale | 指定列的大小 |
| not null | 指定列为 NOT NULL |
| autoIncrement | 指定列为自动增长 |
| embedded | 嵌套字段 |
| embeddedPrefix | 嵌入字段的列名前缀 |
| autoCreateTime | 创建时追踪当前时间,对于 int 字段,它会追踪时间戳秒数,可以使用 nano/milli 来追踪纳秒、毫秒时间戳,例如:autoCreateTime:milli |
| autoUpdateTime | 创建/更新时追踪当前时间,对于 int 字段,它会追踪时间戳秒数,可以使用 nano/milli 来追踪纳秒、毫秒时间戳,例如:autoUpdateTime:milli |
| index | 根据参数创建索引,多个字段使用相同的名称则创建复合索引 |
| uniqueIndex | 与 index 相同,但创建的是唯一索引 |
| check | 创建检查约束,例如 check:age > 13 |
| <- | 设置字段写入的权限,<-:create 只创建、<-:update 只更新、<-:false 无写入权限、<-创建和更新权限 |
| -> | 设置字段读的权限,->:false 无读权限 |
| - | 忽略该字段,- 无读写权限 |