一、三件套介绍
- Gorm
Gorm是一个已经迭代了10+年的功能强大的 ORM 框架,在字节内部被广泛使用并且拥有非常丰富的开源扩展。
- Kitex
Kitex 是字节内部的 Golang 微服务 RPC 框架,具有高性能、强可扩展的主要特点,支持多协议并且拥有丰富的开源扩展。
- Hertz
Hertz 是字节内部的 HTTP 框架,参考了其他开源框架的优势,结合字节跳动内部的需求,具有高易用性、高性能、高扩展性特点。
二、三件套的使用
1、Gorm
(1)Gorm的基础使用
Gorm的约定:
- Gorm 使用名为 ID 的字段作为主键
- 如果没有定义 TableName() 方法,使用结构体的蛇形复数作为表名
- 列名为字段名的蛇形小写
- 使用 CreatedAt、UpdatedAt 字段作为创建、更新时间。
(2)Gorm支持的数据库
Gorm目前支持MySQL、SQLServer、PostgreSQL、SQLite
Gorm 通过驱动来连接数据库,如果需要连接其它类型的数据库,可以复用/自行开发驱动。
import(
"gorm.io/driver/sqlserver"
"gorm. io/gorm"
)
dsn := "sqlserver:// gorm:LoremIpsum86@localhost:9930?database=gorm"
db,err := gorm.Open(sqlserver.Open(dsn),&gorm.Config{})
(3) Gorm创建数据
(4)Gorm查询数据
First的使用踩坑:
- 使用First时,需要注意查询不到数据会返回ErrRecordNotFound
- 使用Find查询多条数据,查询不到数据不会返回错误
使用结构体作为查询条件:
当使用结构体作为条件查询时,Gorm只会查询非零值字段。这意味着如果字段值为0、false或其他零值,该字段不会被用来构建查询条件,使用Map来构建查询条件。
(5)Gorm更新数据
使用struct更新时,只会更新非零值,若需要更新零值可使用Map更新或用select选择字段。
(6)Gorm删除数据
物理删除:
软删除:
Gorm提供了gorm.DeletedAt
用于帮助用户实现软删除
拥有软删除能力的Model调用Delete时,记录不会被从数据库中真正删除。但Gorm会将DeleteAt置为当前时间,并且你不能通过正常的查询方法找到该记录。
使用Unscoped可以查询到被软删除的数据。
(7)Gorm事务
Gorm提供了Tansaction方法用于自动提交事务,避免用户漏泄Commit、Rollback。
(8)Gorm Hook
Gorm提供了CURD的Hook能力。
Hook是在创建、查询、更新、删除等操作之前、之后自动调用的函数。
如果任何Hook返回错误,Gorm将停止后续的操作并回滚事务。
(9) Gorm性能提高
对于写操作(创建、更新、删除),为了确保数据的完整性,Gorm会将它们封装在事务内运行。但这样会降低性能,可以使用SkipDefaultTransaction
关闭默认事务。
使用PrepareStmt
缓存预编译语句可以提高后续调用的速度。
db,err := gorm.Open(mysql.Open("username:password@tcp(localhost:9910)/database?charset=utf8")
&gorm.Config{
SkipDefaultTransaction:true,
PrepareStmt:true},
}
if err != nil {
panic("failed to connect database")
}
(10) Gorm生态
2、Kitex
(1)安装Kitex代码生成工具
(2)定义IDL
使用IDL定义服务和接口。
如果我们要进行RPC,就需要知道对方的接口是什么,需要传什么参数,同时也需要知道返回值是什么样的。这时候就需要通过IDL来约定双方的协议,就像在写代码时需要调用某个函数,我们需要知道函数签名一样。
(3)Kitex生成代码
使用kitex -module example -service example echo.thrift
命令生成代码。
(4)Kitex基本使用
服务默认监听8888端口
(5)Kitex Client发起请求
(6)Kitex服务注册与发现
目前Kitex的服务注册与发现已经对接了主流服务注册与发现中心,如ETCD,Nacos等。
(7)Kitex生态
3、Hertz
(1)Hertz基本使用
使用Hertz实现服务监听8080端口并注册了一个GET方法的路由函数。
package main
import {
"context"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/app/server"
"github.com/cloudwego/hertz/pkg/common/utils"
"github.com/cloudwego/hertz/pkg/protocol/consts"
)
func main(){
h := server.Default(server.WithHostPorts("127.0.0.1:8080"))
h.GET("/ping",func(c context.Context,ctx *app.RequestContext){
ctx.JSON(consts.StatusOK,utils.H{"ping":"pong"})
})
h.Spin()
}
(2)Hertz路由
- Hertz提供了GET、POST、PUT、DELETE、ANY等方法用于注册路由。
- Hertz提供了路由组的能力,支持路由分组的功能
- Hertz提供了参数路由和通配路由,优先级为:静态路由>命名路由>通配路由
(3)Hertz参数绑定
提供了Bind、Validate、BindAndValidate函数用于参数绑定和校验。
(4)Hertz中间件
主要分为客户端中间件与服务端中间件。
如何终止中间件调用链的执行:
- c.Abort
- c.AbortWithMsg
- c.AbortWithStats
服务端中间件:
(5)Hertz Client
提供了HTTP Client用于帮助用户发送HTTP请求
(6)Hertz代码生成工具
Hertz提供了代码生成工具Hz,通过定义IDL文件即可生成对应的基础服务代码