这是我参与【第五届青训营】伴学笔记创作活动的第5天
一、本堂课重点内容
- 1、理解database/sql
- 基本用法
- 设计原理
- 基础概念
- 2、GORM使用简介
- 基本用法
- Model定义
- 惯例约定
- 关联介绍
二、详细知识点介绍
1、理解database/sql
(1)基本用法
【数据库连接】
import driver实现,使用driver+DSN初始化DB连接
import _"github.com/go-sql-driver/mysql"
func main(){
db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/hello")
}
【单条sql语句】
执行一条SQL,通过rows取回返回的数据,处理完毕,需要释放连接
rows, err := db.Query("select id,name from users where id = ?", 1)
if err != nil {
// ...
}
defer rows.Close()
【数据、错误处理】
var users []User
for rows.Next(){
var user User
err := rows.Scan(&user.ID, &user.Name)
if err != nil{
// ...
}
users = append(users, user)
}
if rows.Err() != nil{
// ...
}
(2)设计原理
【连接池】
【Driver连接接口】
2、GORM使用简介
(1)基本用法 - CRUD
1、操作数据库
db.AutoMigrate(&Product{})
db.Migrator().CreateTable(&Product{})
2、创建
user := User{Name:"Jinzhu", Age:18, Birthday:time.Now()}
result := db.Create(&user)
user.ID
result.Error // 返回error
result.RowsAffected // 返回影响的行数
3、批量创建
var users = []User{{Name: "jinzhu1"},{Name:"jinzhu2"},{Name:"jinzhu3"}}
db.Create(&users)
db.CreateInBatches(users, 100)
for _, user := range users{
user.ID // 1,2,3
}
4、读取
var product Product
db.First(&product, 1) // 查询id为1的product
db.First(&product,"code=?","L1212")
result := db.Find(&users, []int{1,2,3})
result.RowsAffected // 返回找到的记录数
errors.Is(result.Error, gorm.ErrRecordNotFound) // First,Last,Take 查不到数据
5、更新某个字段
db.Model(&product).Update("Price":2000)
db.Model(&product).UpdateColumn("Price":2000)
6、更新多个字段
db.Model(&product).Updates(Product{Price:2000, Code:"L1212"})
db.Model(&product).Updates(map[string]interface{}{"Price":2000, "Code":"L1212"})
7、批量更新
db.Model(&Product{}).Where("price < ?", 2000).Updates(map[string]interface{}{"Price": 2000})
8、删除 - 删除product
db.Delete(&product)
(2)Model定义- 惯例约定
(4) 关联
CRUD
// 保存用户及其关联 (Upsert)
db.Save(&User{
Name :"jinzhu",
Languages: []Language{{Name: "zh-CN"},{Name:"en-US"}}
}
//关联模式
langAssociation := db.Model(&user).Association("Languages")
//查询关联
langAssociation.Find(&languages)
// 将汉语,英语语添加到用户掌握的语言中
langAssociation.Append([]LanguageflanguageZH,languageEN3)
// 把用户掌握的语言替换为汉语,德语
langAssociation.Replace([]LanguageflanguageZH,languageDE})
//删除用户掌握的两个语言
langAssociation.Delete(languageZH,languageEN)
//删除用户所有掌握的语言
langAssociation.Clear()
// 返回用户所掌握的语言的数量
LangAssociation.Count()
// 批量模式 Append,Replace
var users = 国Userfuser1,user2,user3}
langAssociation := db.Model(&users).Association("Languages")
// 批量模式 Append,Replace,参数需要与源数据长度相同
//例如:我们有 3个user:将 userA 添加到 user1 的 Team
//将 userB 添加到 user2 的 Team,将 userA、userB、userC 添加到 user3 的 Team
db.Model(&users).Association("Team").Append(&userA, &userB,&[]User{userA, userB, userC})
Preload/Joins预加载
type User struct {
Orders []Order
Profile Profile
}
// 查询用户的时候并找出其订单,个人信息 (1+1 条SQL)
db.Preload("Orders").Preload("Profile").Find(&users)
// SELECT *FROM users;
// SELECT*FROM orders WHERE user_id IN (1,2,3,4);// 一对多/
/ SELECT* FROM profiles WHERE user_id IN (1,2,3,4); // 一对-
// 使用 Join SQL 加载 (单条 JOIN SQL)
db.Joins("Company").Joins("Manager").First(&user,1)
db.Joins("Company",DB .Where(&Company[Alive: true])).Find(&users)
//预加载全部关联 (只加载一级关联)
db.Preload(clause.Associations).Find(&users)
//多级预加载
db.Preload("Orders.0rderItems.Product").Find(&users)
//多级预加载 +预加载全部一级关联db.Preload("Orders.0rderItems.Product").Preload(clause.Associations).Find(&users)
// 查询用户的时候找出其未取消的订单
db.Preloadc("Orders" ,"state NOT IN (?)","cancelled").Find(&users)
db.Preload("Orders", "state = ?", "paid").Preload("Orders.OrderItems").Find(&users)
db.Preload("Orders", func(db *gorm.DB)*gorm.DB {
return db .Order("orders amount DESC")
}).Find(&users)
级联删除
//方法1:使用数据库约束自动删除
type User struct{
ID uint
Name string
Account Account `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
CreditCards []CreditCard `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
Orders []Order `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
}
//需要使用 GORMMigrate 数据库迁移数据库外键才行
db.AutoMigrate(&User{})
//如果未启用软删除,在删除 User 时会自动删除其依赖
db.Delete(&User{})
// 方法2:使用 Select 实现级联删除,不依赖数据库约束及软删除
//删除 user 时,也删除 user 的 account
db.Select("Account").Delete(&user)
/删除 user 时,也删除 user 的 Orders、CreditCards 记录
db.Select("Orders","CreditCards").Delete(&user)
//删除 user 时,也删除 user 的 Orders、CreditCards 记录,也删除订单的 BillingAddress
db.Select("Orders","Orders.BillingAddress","CreditCards").Delete(&user)
//删除 user 时,也删除用户及其依赖的所有 has one/many、many2many 记录
db.Select(clause.Associations).Delete (&user)
三、课后个人总结
之前学过sql的话,这个学起来接受也快。