GORM特性
- 全功能 ORM
- 关联 (Has One,Has Many,Belongs To,Many To Many,多态,单表继承)
- Create,Save,Update,Delete,Find 中钩子方法
- 支持
Preload、Joins的预加载 - 事务,嵌套事务,Save Point,Rollback To Saved Point
- Context、预编译模式、DryRun 模式
- 批量插入,FindInBatches,Find/Create with Map,使用 SQL 表达式、Context Valuer 进行 CRUD
- SQL 构建器,Upsert,数据库锁,Optimizer/Index/Comment Hint,命名参数,子查询
- 复合主键,索引,约束
- Auto Migration
- 自定义 Logger
- 灵活的可扩展插件 API:Database Resolver(多数据库,读写分离)、Prometheus…
- 每个特性都经过了测试的重重考验
- 开发者友好
安装
go get -u gorm.io/gorm
定义模型
模型是使用普通结构体定义的。 这些结构体可以包含具有基本Go类型、指针或这些类型的别名,甚至是自定义类型(只需要实现 database/sql 包中的Scanner和Valuer接口)。
考虑以下 user 模型的示例:
type User struct {
ID uint // Standard field for the primary key
Name string // 一个常规字符串字段
Email *string // 一个指向字符串的指针, allowing for null values
Age uint8 // 一个未签名的8位整数
Birthday *time.Time // A pointer to time.Time, can be null
MemberNumber sql.NullString // Uses sql.NullString to handle nullable strings
ActivatedAt sql.NullTime // Uses sql.NullTime for nullable time fields
CreatedAt time.Time // 创建时间(由GORM自动管理)
UpdatedAt time.Time // 最后一次更新时间(由GORM自动管理)
}
在此模型中:
- 具体数字类型如
uint、string和uint8直接使用。 - 指向
*string和*time.Time类型的指针表示可空字段。 - 来自
database/sql包的sql.NullString和sql.NullTime用于具有更多控制的可空字段。 CreatedAt和UpdatedAt是特殊字段,当记录被创建或更新时,GORM 会自动向内填充当前时间。
除了 GORM 中模型声明的基本特性外,强调下通过 serializer 标签支持序列化也很重要。 此功能增强了数据存储和检索的灵活性,特别是对于需要自定义序列化逻辑的字段。详细说明请参见 Serializer。
约定
- 主键:GORM 使用一个名为
ID的字段作为每个模型的默认主键。 - 表名:默认情况下,GORM 将结构体名称转换为
snake_case并为表名加上复数形式。 例如,一个User结构体在数据库中的表名变为users。 - 列名:GORM 自动将结构体字段名称转换为
snake_case作为数据库中的列名。 - 时间戳字段:GORM使用字段
CreatedAt和UpdatedAt来自动跟踪记录的创建和更新时间。
遵循这些约定可以大大减少您需要编写的配置或代码量。 但是,GORM也具有灵活性,允许您根据自己的需求自定义这些设置。 您可以在GORM的约定文档中了解更多关于自定义这些约定的信息。
gorm.Model
GORM提供了一个预定义的结构体,名为gorm.Model,其中包含常用字段:
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
-
将其嵌入在您的结构体中: 您可以直接在您的结构体中嵌入
gorm.Model,以便自动包含这些字段。 这对于在不同模型之间保持一致性并利用GORM内置的约定非常有用,请参考嵌入结构。 -
包含的字段:
ID:每个记录的唯一标识符(主键)。CreatedAt:在创建记录时自动设置为当前时间。UpdatedAt:每当记录更新时,自动更新为当前时间。DeletedAt:用于软删除(将记录标记为已删除,而实际上并未从数据库中删除)。
连接到数据库
GORM 官方支持的数据库类型有:MySQL, PostgreSQL, SQLite, SQL Server 和 TiDB
MySQL
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
func main() {
// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
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{})
}
注意: 想要正确的处理 time.Time ,您需要带上 parseTime 参数, (更多参数) 要支持完整的 UTF-8 编码,您需要将 charset=utf8 更改为 charset=utf8mb4 查看 此文章 获取详情
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", // DSN data source name
DefaultStringSize: 256, // string 类型字段的默认长度
DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置
}), &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", // data source name, 详情参考:https://github.com/go-sql-driver/mysql#dsn-data-source-name
}), &gorm.Config{})
现有的数据库连接
GORM 允许通过一个现有的数据库连接来初始化 *gorm.DB
import (
"database/sql"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
sqlDB, err := sql.Open("mysql", "mydb_dsn")
gormDB, err := gorm.Open(mysql.New(mysql.Config{
Conn: sqlDB,
}), &gorm.Config{})