ycgg的GO语言之路Day06——GO三件套详解(Gorm)| 青训营笔记

43 阅读4分钟

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

Day06——Go框架三件套详解(1)

01.三件套简介:

1.Gorm

Gorn是个已经选代了10年+的功能强大的ORM框架,在字节内部被广泛使用并且拥有非常丰富的开源扩展。

2.Kitex

Kitex是字节内部的Golang散服务RPC框架,具有高性能、强可扩展的主要特点。支持多协议并且拥有丰富的开源扩展,

3.Hertz

Hertz是字节内部的HTTP框架,参考了其他开源框架的优势,结合字节跳动内部的需求,具有高易用性、高性能、高扩展性特点。

02.三件套的使用

Gorm

Gorm的基本使用

image-20230121151826085.png

其中Product结构体对应数据库中的一张表,为model定义表名需要实现TableName接口,返回表名字符串

gorm.Open连接数据库,根据不同的数据库类型调用对应方法连接,Config对数据库进行配置

Create创建数据,创建一个数据时为对象,创建多条数据时为一个切片

first查询单条记录

gorm中更新时,传递结构时,可以更新非零字段,如果要更新零值,可以使用map

Gorm的约定

  • Gorm使用名为ID的字段作为主键
  • 使用结构体的蛇形负数作为表名
  • 字段名的蛇形作为列名
  • 使用CxeatedAt、UpdatedAt字段作为创建、更新时间

Gorm支持的数据库

GORM目前支持 MySQL、SQLServer、PostgreSQL、SQLite.

image-20230121152938553.png

GORM通过驱动来连接数据库,如果需要连接其它类型的数据库,可以复用/自行开发驱动。

比如有些数据库兼容mysql,可以复用

Gorm创建数据

image-20230121153302099.png

column定义列名,当gorm定义主键时,后续创建数据不传主键,会自增并回填

Create是链式调用,要处理err要返回一个res对象

使用Upsert,使用clause.OnConflict处理数据冲突

主键冲突的情况下,不执行任何操作(适用于有冲突丢弃冲突数据的场景)

Create前面都是在拼接sql,但是Create就是执行sql了,不能在后面 .Where操作

image-20230121153911847.png

定义默认值

image-20230121154314906.png


Gorm查询数据

image-20230121154452204.png

First会根据id升序,查询获得第一条数据,如果拿不到数据会返回err

查询多条数据用find,复杂语句可以用where拼接sql,由于链式调用,可以拼接多个where

使用find查询不到数据时并不会返回错误

当使用结构作为条件查询时,GORM只会查询非零值字段。这意味着如果您的字段值为0、"、 false或其他零值,该字段不会被用于构建查询条件,使用Map来构建查询条件。

Gorm更新数据

image-20230121155433019.png

update会更新单个列,要用model去指定表

使用Struct更新时,只会更新非零值,如果需要更新零值可以使用Map 更新或使用Select选择字段。

要更新指定字段时,使用Select选定

更新操作有关文档:

https://gorm.cn/zh_CN/docs/update.html

Grom删除数据

物理删除(从数据库删除)

image-20230121160115310.png

软删除

image-20230121160146805.png

gorm提供了一个软删除工具

需要额外定义一个Deleted字段,并标注为gorm.DeletedAt

加上软删除字段时,使用Find操作可以忽略,程序会帮我们自动加上

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

也可以通过以下方式查询被软删除的数据

image-20230121160553494.png

正常使用Gorm提供的语句,可以防止sql注入

Gorm事务

Gorm提供了Begin、Commit、Rollback方法用于使用事务

尤其是对数据一致性较强的业务时,需要用事务

image-20230121160840681.png

db.Begin开启事务,开启后一定要返回一个新的tx,下面的操作都要用tx去完成

Gorm提供了Tansaction方法用于自动提交事务,避免用户漏写Commit、Rollbcak.推荐使用该方法

image-20230121161234986.png

如果有错误,Tansaction会自动回滚返回err,rollback可以不写,如果正确会自动提交

Grom Hook

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

image-20230121161536848.png

如例子中,创建前进行参数校验,创建后为其再添加一个邮箱

Hook会带一个默认事务,会保证一致性

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

Gorm性能提高

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

image-20230121162104241.png

使用PrepareStmt缓存预编译语句可以提高后续调用的速度,本机测试提高大约35%左右。

Grom生态扩展

GORM代码生成工具 github.com/go-gorm/gen

GORM分片库方案 github.com/go-gorm/sha…

GORM手动索引 github.com/go-gorm/hin…

GORM乐观锁 github.com/go-gorm/opt…

GORM读写分离 https:/lgithub.com/go-gorm/dbresolver

GORM OpenTelemetry扩展 https:/lgithub.com/go-gorm/opentelemetry