DATABASE/SQL 与 GORM 设计与实践|青训营笔记

151 阅读3分钟

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

理解 database/sql

  • 使用 import 导入 database/sql 包 + 使用 driver +DSN 初始化 DB 连接

    • import{
          "database/sql"
      }
      
  • 使用 sql.open 连接数据库 + 使用 db 变量保存获取到的连接

    • db,err := sql.Open("mysql","user:password@tcp(127.0.0.1:3306)/hello")
      rows,err := db.Query("SQL语句")
      defer rows.Close()
      
  • 使用 db.Query 进行数据查询 + 使用 rows 保存查询到的数据(查询完一定要使用 defer rows.Close 关闭连接)

    • for rows.Next(){
      	err := rows.Scan(&变量)
      	if err != nil{
      		//...
      	}
      }
      if rows.Err() != nil{
          //...
      }
      
  • 注意对 rows.Close 的时候实际上是有可能返回错误的,正确的写法应该是

    • defer func(){
      	err = rows.Close()
      }
      
  • 池化技术提前准备一些资源,在需要时可以重复使用这些预先准备的资源,把一些资源预先分配好,组织到对象池中,之后的业务使用资源从对象池中获取,使用完后放回到对象池中

    • 好处:
      • 资源重复使用, 减少了资源分配和释放过程中的系统消耗;在业务实现上,通常把一些资源预先分配好,如线程池,数据库连接池,Redis连接池,HTTP连接池等,来减少系统消耗,提升系统性能
      • 可以对资源的整体使用做限制;相关资源预分配且只在预分配是生成,后续不再动态添加,从而限制了整个系统对资源的使用上限
      • 池化技术分配对象池,通常会集中分配,这样有效避免了碎片化的问题
  • 在使用连接的时候,尽量复用空闲的连接,只有在没有连接的时候才考虑新建一个连接

  • 所有连接都需要定义 defer 语句将连接放回连接池

  • 在将连接放回连接池的时候,需要对连接进行检查,例如检查是否有错误,还有检查如 max life time,max idle conns 等等属性

  • DB 连接类型:

    • 直接连接 Conn
    • 预编译/Stmt:执行同样的 sql 的时候会与先 prepare 一下,然后生成一个 Prepared Statement,根据这个语句的 reference id,后面进行同样的 sql 的时候,只需要将 id 传递过去而不需要再将语句发送过去
    • 事务 Tx
  • 处理返回数据几种方式:

    • Exec -> Result:只确定结果,执行是否成功(如插入、删除)
    • Query -> Rows
    • QueryRow -> Row(Rows 的简化版):只读取 rows 的一行数据,读取完后自动关闭

GORM 使用简介

  • GORM:设计简洁、功能强大、自由扩展到全功能 ORM
  • 设计原则:API 精简、测试优先、最小惊讶、灵活扩展、无依赖
  • 模型定义的惯例约定(约定优于配置):
    • 表名使用结构体名字蛇形命名法的复数形式
    • 字段名使用属性名的蛇形命名法的单数形式
    • ID 字段为主键,如果为数字则为自增主键
    • CreateAt 字段为创建时保存当前时间
    • UpdateAt 字段为创建、更新时保存当前时间
    • grom.DeleteAt 字段,默认开启 soft delete 模式

GORM 设计原理

  • GORM STATEMENT 有多个部分构成
    • 多个 where 子句
    • Limit 子句
    • Order 子句
    • Find|Create|Delete 子句
    • 其中除了 find 子句被称为 Finisher Method,表明决定类型或者执行,其他都被称为 chain method,用于约束条件或者排序等