GORM设计模式 | 青训营笔记

330 阅读3分钟

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

GORM设计模式

  1. 理解database/sql
    1. 基本用法
      • import driver实现
      • 使用driver+DSN初始化DB连接
      • 执行SQL,通过rows取回返回的数据
      • 处理完毕,释放连接
      • tips:
        • 记得rows使用完毕需要关闭
        • rows关闭时可能会返回异常
        • rows会返回和数据无关的一些error
    2. 设计原理
      • 采用极简接口设计的原则,对上层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接口返回数据
  2. GORM使用简介
    1. 基本用法
      • ...
      • tips
        • 不需要import driver
        • 避免遗忘close Rows
    2. 惯例约定
      • 约定优于配置
        • 表名为struct name的snake_cases复数格式
        • 字段名为filed name的sanke_case 单数格式
        • ID/Id字段为主键,如果为数字,则为自增主键
        • CreatedAt字段,创建时,保持当前时间
        • UpdatedAt字段,创建、更新时,保持当前时间
        • gorm.DeletedAt字段,默认开启soft delete模式
      • 一切皆可配置
    3. 关联操作
      • 支持一对一、一对多、多对多关系
      • Preload/Joins预加载
  3. 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
    • 插件
      • Finisher->决定Statement类型->执行Callbacks->生成SQL并执行
      • 通过Callbacks插入方法,Register,Remove,Replace
      • 检查条件Match
    • 灵活定制自由扩展
      • 多租户
      • 多数据库、读写分离
      • 加解密、混沌工程
    • GORM->ConnPool->数据库
    • ConnPool会缓存预编译的SQL
    • Dialector接口
      • 定制SQL生成
      • 定制GORM插件
      • 定制ConnPool
      • 定制企业特性逻辑
    • Options接口
  4. GORM最佳实践
    • 实现GormValuer接口
    • 实现clause.Expression接口
    • 实现Serializer接口
      • Scan
      • Value
    • 优化加速
      • 批量创建
      • 批量查询
      • 关闭默认事务
      • 使用SkipHooks跳过
      • Prepared Statement
      • 代码复用、分库分表、Sharding
    • Logger/Trace
    • Raw SQL
    • Gen代码生成