Gorm简介
Gorm是一个已经迭代了10年+的,功能强大的ORM框架,在字节内部被广泛使用并且拥有非常丰富的开源扩展。
什么是ORM框架?
-
对象-关系映射(Object-Relational Mapping,简称ORM)
-
对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。
-
因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。
-
ORM使数据库结构文档化。比如MySQL数据库就被ORM转换为了java程序员可以读懂的java类,java程序员可以只把注意力放在他擅长的java层面
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…
Gorm支持的数据库
GORM 目前支持 MySQL、SQLServer、PostgreSQL、SQLite。
GORM通过驱动来连接数据车,如果需要连接具它类型的数据库,以复用/自行开发驱动。
- 复用:比如有些数据库兼容Mysql那么就可以使用Mysql的驱动链接该数据库
安装Gorm
官方中文文档: gorm.io/zh_CN/
- 在GoLand中打开项目,点击终端
- 在终端中依次输入以下语句进行安装:
go get -u gorm.io/gorm go get -u gorm.io/driver/mysql # 如果要使用其他数据库则要go get 其他数据的驱动
待程序执行完,即安装完成。
快速入门:代码解释
package main
import (
"gorm.io/driver/mysql" //这里我们import了Mysql的驱动
"gorm.io/gorm" //这里imoort了gorm
)
type Product struct { //这里通过结构体定义了Gorm Model
gorm.Model
Code string
Price uint
}
func (p Product) TableName() string{ //为model定义表名
return "product"
}
func main() {
db, err := gorm.Open(mysql.Open("test.db"), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
// 迁移 schema
db.AutoMigrate(&Product{})
// Create
db.Create(&Product{Code: "D42", Price: 100})
// Read
var product Product
db.First(&product, 1) // 根据整形主键查找
db.First(&product, "code = ?", "D42") // 查找 code 字段值为 D42 的记录
// 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)
}
尝试
数据库表的构造
代码:
type book struct { //这里通过结构体定义了Gorm Model
Bookname string //注意:结构体里的字段均要以大写字母开头
Author string
Price int
}
func (b book) TableName() string { //为model定义表名
return "book"
}
func main() {
//这里创建了DSN,元素分别是:[用户名]:[密码]@[协议][(ip:port)]/[链接的数据库名称]
dsn := "root:123456@tcp(127.0.0.1:3306)/py_test"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
//到这个位置我们创建了一个DB对象
if err != nil {
panic("failed to connect database") //处理错误
}
db.Create(&book{Bookname: "熊镇", Author: "弗雷德里克·巴克曼", Price: 49})
//等同于:INSERT INTO `book` (`Bookname`,`Author`,`Price`) VALUES ('熊镇','弗雷德里克·巴克曼',49)
执行语句后:
在数据库中查看:成功将数据加入至表中
其他的演示建议去GORM的官方文档中查看,这里不在赘述
其他一些补充知识
DSN(数据源名称)
DSN具有通用格式,可以像PEAR DB一样使用它,但没有类型前缀(可选部分用方括号标记):
[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...¶mN=valueN]
完整形式的DSN:
username:password@protocol(address)/dbname?param=value
除数据库名称外,所有值都是可选的。因此,最小DSN为:
/dbname
如果不想预先选择数据库,请留空:dbname
/
这与空 DSN 字符串具有相同的效果:
dbname自 v1.8.0 起由 PathEscape()pkg.go.dev/net/url#Pat… 转义。如果数据库名称为,则变为:dbname/withslash
/dbname%2Fwithslash
或者,Config.FormatDSN 可用于通过填充结构来创建 DSN 字符串。
结构体和JSON
结构体的每个字段都使用了json标签,表示该字段在JSON数据中的键名。然后我们定义了一个JSON字符串变量,使用json.Unmarshal方法将JSON数据转化为结构体。转化成功后,我们可以通过结构体的字段值访问到JSON数据的各个字段。