设计模式之 Database/SQL 与 GORM 实践 | 青训营笔记

215 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第1篇笔记。

理解 database/sql

import driver实现 使用driver + DSN初始化DB连接,

Quick start

db,err := sql.Open("mysql","user:password@tcp(localhost:3306)/hello)

执行一条sql,通过rows取回返回的数据。处理完毕,需要释放连接。

rows,err := db.Query("...",1)

defer rows.Close()

image.png

GORM基础使用

  • 设计原则:API精简、测试优先、灵活扩展、无依赖、可信赖

  • 功能完善: 关联:一对一、一对多、单表自关联、多态;Preload、Joins预加载、级联删除;关联模式;自定义关联表

事务:事务代码块、嵌套事务、Save Point

多数据库、读写分离、命名参数、Map、子查询、分组条件、代码共享、SQL表达式(查询、创建、更新)、自动选字段、查询优化器

字段权限、软删除、批量数据处理、Prepared Stmt、自定义类型、命名策略、虚拟字段、自动track时间、SQL Builder、Logger

代码生成、复合主键、Constraint、Prometheus、Auto Migration、多模式灵活自由扩展

GORM设计原理

DB连接的几种类型:

直接连接/Conn 预编译/Stmt 事务/Tx

处理返回数据的几种方式

Exec/ExecContext -> Result

Query/QueryContext -> Rows(Columns)

QueryRow/QueryRowContext -> Row(Rows简化)

操作数据库

db.AutoMigrate(&Product{})
db.Migrator().CreateTable(&Product{})

创建

user := User{Name:"Jinzhu",Age:18,Birthday:time.Now()}
result := db.Create(&user)

批量创建

var users = []User{{Name:"jinzhu1"},{Name:"jinzhu2"},{Name:"jinzhu3"}}
db.Create(&users)
db.CreateInBatches(users,100)
for _,user := range users{
	user.ID
}

读取

var product Product
db.First(&product,1) 	// 查询id为1的product
result := db.Find(&users,[]int{1,2,3})
result.RowsAffected		// 返回找到的记录数
errors.Is(result.Error,gorm.ErrRecordNotFound)

更新某个字段

db.Model(&product).Update("Price",2000)

更新多个字段

db.Model(&product).Updates(Product{Price:2000,Code:"L1212"})
db.Model(&product).Updates(map[string]interface{}{"Price":2000,"Code":"L1212"})

批量更新

db.Model(&Product{}).Where("price < ?",2000).Updates(map[string]interface{}{"Price":2000})

删除product

db.Delete(&product)

模型定义

约定大于配置

GORM设计原理

SQL生成

自定义Clause Builder

插件扩展

多租户、多数据库、读写分离、加解密、混沌工程。。。

ConnPool

image.png

Dialector

GORM最佳实践

image.png