Golang框架三件套 | 青训营笔记

112 阅读5分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天


下面主要是我个人听课时的一些笔记

个人笔记

  • gorm

    GORM 指南

    ORM框架

    对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中

    ORM框架是连接数据库的桥梁

    • db.First()的使用踩坑

      使用First 时,需要注意查询不到数据会返回ErrRecordNotFound

      使用Find查询多条数据,查询不到数据不会返回错误。

      所以一般使用db.Find(),在查询不到数据的时候会返回一个空切片,不会抛出错误

      u := &User{}
      // 获取第一条记录(主键升序)
      db.First(&u)
      // SELECT * FROM users ORDER BY id LIMIT 1;
      
      // 获取全部记录
      result := db.Find(&users)
      // SELECT * FROM users;
      
    • 使用结构体作为查询条件

      当使用结构作为条件查询时,GORM只会查询非零值字段。

      这意味着如果字段值为0、''、false 或其他零值,该字段不会被用于构建查询条件,使用Map来构建查询条件

      // Struct
      db.Where(&User{Name: "jinzhu", Age: 20}).First(&user)
      // SELECT * FROM users WHERE name = "jinzhu" AND age = 20 ORDER BY id LIMIT 1;
      
      // Map
      db.Where(map[string]interface{}{"name": "jinzhu", "age": 20}).Find(&users)
      // SELECT * FROM users WHERE name = "jinzhu" AND age = 20;
      
      // 主键切片条件
      db.Where([]int64{20, 21, 22}).Find(&users)
      // SELECT * FROM users WHERE id IN (20, 21, 22);
      
    • Updates 方法支持 structmap[string]interface{} 参数。

      更新时同理,如果要更新为零值,需要使用map;通过select选择字段

      当使用了 Model 方法,且该对象主键有值,该值会被用于构建条件

      // User 的 ID 是 `111`
      db.Model(&user).Update("name", "hello")
      // UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;
      
      // 根据条件和 model 的值进行更新
      db.Model(&user).Where("active = ?", true).Update("name", "hello")
      // UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111 AND active=true;
      

      使用struct更新多个列

      当使用 struct 更新时,默认情况下,GORM 只会更新非零值的字段

      // 根据 `struct` 更新属性,只会更新非零值的字段
      db.Model(&user).Updates(User{Name: "hello", Age: 18, Active: false})
      // UPDATE users SET name='hello', age=18, updated_at = '2013-11-17 21:34:10' WHERE id = 111;
      

      使用map更新多个列

      // 根据 `map` 更新属性
      db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
      // UPDATE users SET name='hello', age=18, actived=false, updated_at='2013-11-17 21:34:10' WHERE id=111;
      
    • 删除数据

      物理删除db.Delete()

      软删除:在结构体中加上gorm.DeletedAt字段

      如果模型包含了一个 gorm.deletedat 字段(gorm.Model 已经包含了该字段),它将自动获得软删除的能力

      拥有软删除能力的模型调用 Delete 时,记录不会被从数据库中真正删除。但 GORM 会将 DeletedAt 置为当前时间, 并且你不能再通过正常的查询方法找到该记录。

      可以使用 Unscoped 找到被软删除的记录

    • 链式调用时,Where()这种api是用来拼SQL的

      First()Find()Create()Update()Delete()这种api会直接执行SQL,后面再加Where()不会生效

    • 事务

      db.Begin()会返回固化链接,所以要使用tx,而不是db,db是golang维护的链接池

      Gorm也提供了Transaction方法用于自动提交事务,避免用户漏写Commit、Rollback

    • Hook

      GORM提供了CURD的Hook能力。

      Hook是在创建、查询、更新、删除等操作之前、之后自动调用的函数。

      如果任何Hook返回错误,GORM将停止后续的操作并回滚事务。

    • GORM性能提升

      • 关闭默认事务
      • 缓存预编译语句
      • 等等

      对于写操作(创建、更新、删除),为了确保数据的完整性,GORM会将它们封装在事务内运行。但这会降低性能,可以使用SkipDefaultTransaction关闭默认事务。

      使用PrepareStmt缓存预编译语句可以提高后续调用的速度

  • Kitex

    RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP/IP或UDP,为通信程序之间携带信息数据。RPC将原来的本地调用转变为调用远端的服务器上的方法,给系统的处理能力和吞吐量带来了近似于无限制提升的可能。在OSI网络通信模型中,RPC跨域了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。

    具体使用见Kitex官方文档

  • Hertz

    Hertz是一个 Golang 微服务 HTTP 框架

    官方文档:CloudWeGo-Hertz

    Hertz[həːts] 是一个 Golang 微服务 HTTP 框架,在设计之初参考了其他开源框架 fasthttp、gin、echo 的优势, 并结合字节跳动内部的需求,使其具有高易用性、高性能、高扩展性等特点,目前在字节跳动内部已广泛使用。

参考