网站首页 > 技术文章 正文
gorm 是 golang web 编程中十分常用的数据库关系映射库.
gorm 简介
ORM (Object Relational Mapping) 是实现程序对象到关系数据库的一种映射. 它可以使得编程语言能高效操作数据. ORM 具有简单、精确、易懂、易用的特点.
GORM 是 jinzhu 大神开发的 go 语言 ORM 框架,也是目前 golang 中最常用的 ORM 框架. jinzhu 大神目前正在筹划 gorm 2.0. 作为 go web 开发者,是十分有必要了解 gorm 库的.
gorm 实现了几乎所有 ORM 框架的特性, 它的特性涵盖:
- 关联(包含一个,包含多个,属于,多对多,多种包含)
- Callbacks(创建/保存/更新/删除/查找之前/之后)
- 预加载(急加载)
- 事务
- ?复合主键
- SQL Builder(它可以生成 sql 语句的函数库)
- 自动迁移(表结构的增量修改)
- 日志
- 可扩展,编写基于GORM回调的插件
- 每个功能都有测试
- 开发人员友好
gorm 基础操作
2.1 CRUD 操作
连接数据库, 首先需要通过 gorm 连接数据库,使用 gorm.Open() 函数进行连接,并导入相应的驱动,以及连接字符串 connection,如 mysql , 如下:
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
func main() {
db, err := gorm.Open("mysql",
"user:password@/dbname?charset=utf8&parseTime=True&loc=Local")
defer db.Close()
}
创建数据表, 可以通过 gorm.DB.CreateTable 进行表的创建. 如下:
// 为模型`User`创建表
db.CreateTable(&User{})
// 创建表`users'时将“ENGINE = InnoDB”附加到SQL语句
db.Set("gorm:table_options", "ENGINE=InnoDB").CreateTable(&User{})
更新数据表
根据对象的值更新数据库的记录
db.First(&user)
user.Age = 100
db.Save(&user)
更新对象的非零值( golang 的每个类型都有零值)到数据库中
db.Updates(&product)
更新全部字段(根据主键)
db.Select("*").Updates(&product)
更新除了某个字段外的其它字段
db.Omit("*").Updates(&product)
更新特定字段
db.Select("code", "Price").Updates(&product)
更新除 code 外的非零值字段
db.Omit("Code").Updates(&product)
更新除 code 外的全部字段
db.Select("*").Omit("Code").Updates(&product)
更新指定字段
db.Select("Price").Updates(map[string]interface{"Price": 200,
"Name":"T-shirt"})
删除数据表
删除记录,需要确保主要字段(主键)不为空,否则将删除模型的所有记录
db.Delete(&email)
删除所有匹配的记录
db.Where("email LIKE ?", "%pilatus%").Delete(Email{})
2.2 关联
关系型数据库的表可以存在多种关联关系,如:
- 一对一: one_to_one,包括 has_one 或 belongs_to
- 一对多: one_to_many, 包括 has_many、belongs_to
- 多对多: many_to_many
gorm 在进行数据表多关联定义时,也支持关联定义. 下面的代码中,User 拥有一个 Account(has one) ,拥有多个 Pets (has many), 多个 Toys(has many),属于某个 Company(belongs to),属于某 Manager(belongs to),会多种 languages(many to many),拥有很多 friends(many to many 单表),Pet 有一个玩具 Toy(has one 多态)
type User struct {
gorm.Model
Name string
Account Account
Pets []*Pet
Toys []Toy `gorm:"polymorphic:Owner"`
CompanyID *int
Company Company
ManagerID *uint
Manager *User
Team []User `gorm:"foreignkey:ManagerID;""`
Languages []Language `gorm:"many2many:UserSpeak;""`
Friends []*User `gorm:"many2many:user_friends;""`
}
type Account struct {
gorm.Model
}
type Company struct {
gorm.Model
}
type Pet struct {
gorm.Model
UserID int
Toy Toy `gorm:"polymorphic:Owner;"`
}
gorm 进阶用法
3.1 preload 预加载
gorm 提供 Preload 可以预加载数据,使用方式如下:
type User struct{
gorm.Model
Profile Profile
Orders []Order
}
type Order struct{
gorm.Model
State string
}
db.Preload("Orders").Find(&user)
db.Preload("Orders","state NOT IN(?)", "cancelled").Find(&user)
db.Preload("Orders.CreditCard").Find(&users)
db.Joins("Profile").Find(&users)
3.2 migrate
gorm 提供了 migrator 用于更新数据库表结构, gorm 2.0 即将提供 migrator. 通过 AutoMigrate 可以将表结构自动进行更新,但是为了保护数据并不会改变现有列的类型或删除未使用的列,其用法如下:
db.AutoMigrate(&User{})
db.AutoMigrate(&User{}, &Product{}, &Order{})
// 创建表时添加表后缀
db.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(&User{})
3.3 勾子(hook)
在 gorm 的使用过程中,可能涉及 map 等复杂数据类型与数据库 model 字段的绑定. 这些可以通过勾子(hook) 实现. 如下述代码所示:
// Save 保存前/后
func (u *User) BeforeSave(tx *gorm.DB) (err error)
// Create 创建前/后
func (u *User) AfterCreate(tx *gorm.DB) (err error)
// Update 更新数据前/后
func (u *User) BeforeUpdate(tx *gorm.DB) (err error)
// Before/After Delete 更新数据前后调用
func (u *User) AfterDelete(tx *gorm.DB) (err error)
// 查询数据后调用
func (u *User) AfterFind(tx *gorm.DB) (err error)
3.4 sql/database
gorm 连接数据库需要使用相应数据库的 go 语言驱动,如 mysql、postgresql、sqlite、mssql 等. 为了方便使用,gorm 封装了这些驱动到 gorm package 中. 如:
github.com/jinzhu/gorm/dialects/mysql
github.com/jinzhu/gorm/dialects/postgres
github.com/jinzhu/gorm/dialects/sqlite
github.com/jinzhu/gorm/dialects/mssql
3.5 事物
对于一系列的 sql 操作,可以使用事务进行, gorm 提供的事务流程如下:
// 开始事务
tx := db.Begin()
// 在事务中做一些数据库操作(从这一点使用'tx',而不是'db')
tx.Create(...)
// ...
// 发生错误时回滚事务
tx.Rollback()
// 或提交事务
tx.Commit()
// 例子如下
func CreateAnimals(db *gorm.DB) err {
tx := db.Begin()
// 注意,一旦你在一个事务中,使用tx作为数据库句柄
if err := tx.Create(&Animal{Name: "Giraffe"}).Error; err != nil {
tx.Rollback()
return err
}
if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil {
tx.Rollback()
return err
}
tx.Commit()
return nil
}
3.6 代码复用
gorm 提供了代码复用机制,可以提升编码效率,让不通对象相似功能的可以复用代码. 例子如下:
func Paginate(r *http.Request) func(*gorm.DB) *gorm.DB{
return func(db *gorm.DB) *gorm.DB{
return db.Offset(offset).Limit(perPage)
}
}
// 复用上述d代码
db.Scopes(Paginate(r)).Find(&users)
db.Scopes(Paginate(r)).Find(&articles)
db.Scopes(Paginate(r)).Find(&products
END
4.1 插件系统
- 扩展 API
- 基于插件系统的功能
- 定制 GORM 功能
4.2 参考资料
1. gorm 介绍与展望 https://talkgo.org/night/81-2020-03-19-gorm-guide/
猜你喜欢
- 2024-09-09 混合云资产管理项目(二)(混合云存储产品有哪些)
- 2024-09-09 Go语言进阶之Go语言高性能Web框架Iris项目实战-完善用户管理EP04
- 2024-09-09 数据库与 Go 的交互(go数据库和kegg数据库)
- 2024-09-09 七爪源码:N+1 查询如何烧毁您的数据库
- 2024-09-09 Go的安全编程和防御性编程(防止代码注入)
- 2024-09-09 Vue3+Go 仿抖音项目架构设计与实现
- 2024-09-09 腾讯Go安全指南(腾讯官网最新安全公告)
- 2024-09-09 Grails指南24查询高阶(grails中文参考手册)
- 2024-09-09 Redis优化高并发下的秒杀性能(redis秒杀高并发代码)
- 2024-09-09 10.Go语言编写个人博客 文章分类(基于golang的个人博客系统)
- 02-21走进git时代, 你该怎么玩?_gits
- 02-21GitHub是什么?它可不仅仅是云中的Git版本控制器
- 02-21Git常用操作总结_git基本用法
- 02-21为什么互联网巨头使用Git而放弃SVN?(含核心命令与原理)
- 02-21Git 高级用法,喜欢就拿去用_git基本用法
- 02-21Git常用命令和Git团队使用规范指南
- 02-21总结几个常用的Git命令的使用方法
- 02-21Git工作原理和常用指令_git原理详解
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)