这是我参与「第三届青训营 -后端场」笔记创作活动的的第三篇笔记
GORM设计模式
- 理解database/sql
- 基本用法
- import driver实现
- 使用driver+DSN初始化DB连接
- 执行SQL,通过rows取回返回的数据
- 处理完毕,释放连接
- tips:
- 记得rows使用完毕需要关闭
- rows关闭时可能会返回异常
- rows会返回和数据无关的一些error
- 设计原理
- 采用极简接口设计的原则,对上层api提供统一的接口,database/sql包中实现连接池的管理
- 支持不同数据库设计不同的连接接口和操作接口,给用户提供一致的操作接口
- 使用池化技术优化性能,把昂贵的资源放到连接池中,连接池同时提供包括探活和强制回收等机制
- 连接池配置,连接池状态,实现对连接池进行管理
- 操作过程:
- 获取一个连接,如果连接池中存在空闲连接则可以从连接池中获取否则从driver获取
- 执行对应操作
- 判断操作是否成功,不成功则重试若干次
- 将连接放回连接池
- 连接接口
- Driver接口:传入一个DSN,返回一个连接
- 注册:传入一个driver的name和一个实现了Driver接口的对象进行注册,name相同则会panic
- tips:
- 多次重试有可能导致重复数据
- 默认的通过DSN创建连接会带来一些问题:
- DSN过长,很难了解其参数含义,dialect等不能通过DSN传递,只能通过hack的方式实现
- 有的用户密码等不能通过DSN表达
- 用户可能遗忘import对应的driver,而不会出现编译时异常,只有在runtime时才会panic
- 对于name相同的driver不能同时import,同时import会导致panic
- 新的结构体创建方式缺少文档介绍很少有人使用
- DB连接类型
- 直接连接/Conn
- 预编译/Stmt
- 事务/Tx
- 数据处理方式
- Exec->Result
- Query->Rows(Columns)
- QueryRow->Row(Rows简化)
- Driver实现Rows接口返回数据
- 基本用法
- GORM使用简介
- 基本用法
- ...
- tips
- 不需要import driver
- 避免遗忘close Rows
- 惯例约定
- 约定优于配置
- 表名为struct name的snake_cases复数格式
- 字段名为filed name的sanke_case 单数格式
- ID/Id字段为主键,如果为数字,则为自增主键
- CreatedAt字段,创建时,保持当前时间
- UpdatedAt字段,创建、更新时,保持当前时间
- gorm.DeletedAt字段,默认开启soft delete模式
- 一切皆可配置
- 约定优于配置
- 关联操作
- 支持一对一、一对多、多对多关系
- Preload/Joins预加载
- 基本用法
- GORM设计原理
- SQL生成
- Chain method
- where添加clauses至GORM statement
- GORM Finisher方法执行GORM Statement
- Finisher设置目标值
- Finisher通过Query等方法取出对应的子句并返回processor
- processor将对应的子句编译成sql语句交给连接池执行
- 自定义Builder
- 通过数据库版本使用不同的sql生成策略
- 扩展子句
- 通过hints包进行扩展
- 查询优化器
- 扩展From使用索引,UserIndex,ForceIndex
- 自由扩展CommentBefore,CommentAfter
- 通过hints包进行扩展
- 插件
- Finisher->决定Statement类型->执行Callbacks->生成SQL并执行
- 通过Callbacks插入方法,Register,Remove,Replace
- 检查条件Match
- 灵活定制自由扩展
- 多租户
- 多数据库、读写分离
- 加解密、混沌工程
- GORM->ConnPool->数据库
- ConnPool会缓存预编译的SQL
- Dialector接口
- 定制SQL生成
- 定制GORM插件
- 定制ConnPool
- 定制企业特性逻辑
- Options接口
- SQL生成
- GORM最佳实践
- 实现GormValuer接口
- 实现clause.Expression接口
- 实现Serializer接口
- Scan
- Value
- 优化加速
- 批量创建
- 批量查询
- 关闭默认事务
- 使用SkipHooks跳过
- Prepared Statement
- 代码复用、分库分表、Sharding
- Logger/Trace
- Raw SQL
- Gen代码生成