这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天
主要记录课程的重点和课上所讲项目的每一步以及我的思考
今天的课程主要讲解了GORM,Kitex,Hertz 的基本使用方法。因为时间和学习进度问题,本次笔记将主要讲解GORM的内容。
Gorm
概念
首先我们要了解ORM的概念,ORM(Object Relational Mapping),意思是对象关系映射。 数据库会提供官方客户端驱动,但是需要自己处理 SQL 和结构体的转换。 使用 ORM 框架让我们避免转换,写出一些无聊的冗余代码。理论上 ORM 框架可以让我们脱离 SQL,但实际上还是需要懂 SQL 才可以使用 ORM。Gorm 是 Golang 的一个ORM框架。Gorm官方支持的数据库类型有: MySQL, PostgreSQL, SQlite, SQL Server
Gorm的基本使用
连接数据库
首先要导入Gorm和MySQL驱动
import ( "gorm.io/driver/mysql" // gorm mysql 驱动包
"gorm.io/gorm"// gorm
)
连接
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local&timeout=%s", username, password, host, port, DBname, timeout) // Open 连接
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic("failed to connect mysql.")
}
创建数据
使用 db.Create 方法,传入结构体的指针创建
user := User{UserName: "l", Password: "ddd"}
result := db.Create(&user)
常用的插入数据
fmt.Println("ID:", user.ID) // 插入的主键
fmt.Println("error:", result.Error) // 返回的 error
fmt.Println("rowsAffected:", result.RowsAffected) // 插入的条数
通过select选择指定字段
user := User{UserName: "lzq", Password: "ccc"}
result := db.Select("UserName").Create(&user)
当需要批量插入时,传入一个切片即可
users := []User{
{UserName: "lzq", Password: "aaa"},
{UserName: "qqq", Password: "bbb"},
{UserName: "gry", Password: "ccc"},
}
db.Create(&users)
查询数据
查询单个对象
gorm 提供了 First、Take、Last 方法。它们都是通过 LIMIT 1 来实现的,分别是主键升序、不排序和主键降序
user := User{}
// 获取第一条记录(主键升序)
db.First(&user)
// SELECT * FROM users ORDER BY id LIMIT 1;
// 获取一条记录,没有指定排序字段
db.Take(&user)
// SELECT * FROM users LIMIT 1;
// 获取最后一条记录(主键降序)
db.Last(&user)
// SELECT * FROM users ORDER BY id DESC LIMIT 1;
根据主键查询
在 First/Take/Last 等函数中设置第二个参数,该参数被认作是 ID。可以选择 int 或 string 类型
db.First(&user, 10)
db.First(&user, "10")
查询多个对象
使用 Find 方法查询多个对象
users := []User{}
result := db.Find(&users)
更新数据
更新所有字段
使用 Save 方法更新所有字段,即使是零值也会更新
db.First(&user)
user.UserName = ""
db.Save(&user)
更新单列
使用 Model 和 Update 方法更新单列。
可以使用结构体作为选取条件,仅选择 ID
user.ID = 12
db.Model(&user).Update("user_name", "lzq")
也可以在 Model 中设置空结构体,使用 Where 方法自己选取条件
db.Model(&User{}).Where("user_name", "gry").Update("user_name", "gry2")
更新多列
使用 Updates 方法进行更新多列。支持 struct 和 map 更新。当更新条件是 struct 时,零值不会更新,如果确保某列必定更新,使用 Select 选择该列
删除数据
物理删除
db.Unscoped().Delete(&order) // DELETE FROM orders WHERE id=10;
软删除
如果您的模型包含了一个 gorm.deletedat 字段(gorm.Model 已经包含了该字段),它将自动获得软删除的能力。拥有软删除能力的模型调用 Delete 时,记录不会被从数据库中真正删除。但 GORM 会将 DeletedAt 置为当前时间, 并且你不能再通过正常的查询方法找到该记录。
// user 的 ID 是 `111`
db.Delete(&user)
// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE id = 111;
// 批量删除
db.Where("age = ?", 20).Delete(&User{})
// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE age = 20;
// 在查询时会忽略被软删除的记录
db.Where("age = 20").Find(&user)
// SELECT * FROM users WHERE age = 20 AND deleted_at IS NULL;
可以使用 Unscoped 找到被软删除的记录
db.Unscoped().Where("age = 20").Find(&users)
// SELECT * FROM users WHERE age = 20;
事物
要在事务中执行一系列操作,一般流程如下:
db.Transaction(func(tx *gorm.DB) error {
// 在事务中执行一些 db 操作(从这里开始,您应该使用 'tx' 而不是 'db')
if err := tx.Create(&Animal{Name: "Giraffe"}).Error; err != nil {
// 返回任何错误都会回滚事务
return err
}
if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil {
return err
}
// 返回 nil 提交事务
return nil
})
Hook
Hook 是在创建、查询、更新、删除等操作之前、之后调用的函数。
如果您已经为模型定义了指定的方法,它会在创建、更新、查询、删除时自动被调用。如果任何回调返回错误,GORM 将停止后续的操作并回滚事务。
总结
本次课程讲解了三个主流框架,并有实战演示。因为精力问题,这次学习并不太好,也没用预先安装好相应的程序,没有办法跟着一块做。在明后天会再次补上。
引用
该文章部分内容来自于以下课程或网页: