这是我参与「第五届青训营 」伴学笔记创作活动的第 8 天
GORM 是基于 Go 语言的一个自动化的 ORM(Object Relational Mapping) 框架,用于对 Go 语言结构体和数据库字段之间的映射。
GORM 官方支持的数据库类型有四个
- MySQL(最流行的数据库)
- PostgreSQL(开源协议较为宽松,很多有定制数据库需求的公司都会基于PostgreSQL进行二开)
- SQLite(轻量级的关系型数据库,主要用于移动设备)
- SQL Server(微软推出的关系型数据库管理系统)
本文主要基于 MySQL 进行介绍。
官方文档地址:GORM - The fantastic ORM library for Golang, aims to be developer friendly.
(吐槽下,作为国产的ORM框架,中文文档居然没汉化完)
安装
命令行输入
go get -u gorm.io/gorm
go get gorm.io/driver/mysql
其实先复制样例代码然后
go mod tidy
也可以
约定与结构体定义
GORM 倾向于约定优于配置。默认情况下,GORM 会使用 ID 作为主键,使用结构体名的 蛇形复数 作为表名,字段名的 蛇形 作为列名。
(虽然个人觉得蛇形复数作为表名非常的抽象,而且这个复数也只是简单的加个s,所以基本是自己定义表名)
模型声明
// Product 定义 gorm model
type Product struct {
ID uint
Code string
Price uint
}
结构体实现 TableName() 方法来指定表名
// TableName 为 model 指定表名
func (p Product) TableName() string {
return "product"
}
可以使用 tag 来配置结构体字段的信息,tag 名大小写不敏感,但建议使用驼峰形式。
基本使用
连接数据库
db, err := gorm.Open(
mysql.Open("root:123456@tcp(127.0.0.1:3306)/gorm_learn?charset=utf8mb4&parseTime=True&loc=Local"),
&gorm.Config{})
if err != nil {
panic("failed to connect database")
}
gorm.Open() 的第一个参数是 DSN(数据资源名)
英文定义如下
DSN (Data Source Name)
The Data Source Name has a common format, like e.g. PEAR DB uses it, but without type-prefix (optional parts marked by squared brackets):
[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...¶mN=valueN]
配置数据库自动更新
err = db.AutoMigrate(&Product{})
if err != nil {
panic(err)
return
}
创建数据
// Create
db.Create(&Product{Code: "D42", Price: 100})
查找数据
// Read
var product Product
db.First(&product, 1)
//根据整形主键查找
db.First(&product, "code=?", "D42") //查找ccode字段值为D42的记录
这里注意 First() Take() Last() 等方法会使用 limit 1,在查询不到数据时会返回 ErrRecordNotFound 。
而使用Find查询多条数据,查询不到数据不会返回错误。故推荐使用Find()查询数据再判断影响的数据行数。
var products []Product
db.Find(&products)
if db.RowsAffected != 0 { // 查询到了数据
// code
}
更新数据
// Update-将product的price更新为200
db.Model(&product).Update("Price", 200)
// Update-更新多个字段
db.Model(&product).Updates(Product{Price: 200, Code: "F42"}) //仅更新非零值字段
db.Model(&product).Updates(map[string]interface{}{"Price": 200, "Code": "F42"})
删除数据
// Delete-删除 product
db.Delete(&product, 1)