Go框架三件套详解 | 青训营

63 阅读4分钟

一、三件套介绍

  • Gorm

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

  • Kitex

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

  • Hertz

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

二、三件套的使用

1、Gorm

(1)Gorm的基础使用

Gorm的约定:

  • Gorm 使用名为 ID 的字段作为主键
  • 如果没有定义 TableName() 方法,使用结构体的蛇形复数作为表名
  • 列名为字段名的蛇形小写
  • 使用 CreatedAt、UpdatedAt 字段作为创建、更新时间。

image.png

(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创建数据

image.png

(4)Gorm查询数据

First的使用踩坑:

  • 使用First时,需要注意查询不到数据会返回ErrRecordNotFound
  • 使用Find查询多条数据,查询不到数据不会返回错误

使用结构体作为查询条件:

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

image.png

(5)Gorm更新数据

使用struct更新时,只会更新非零值,若需要更新零值可使用Map更新或用select选择字段。

image.png

(6)Gorm删除数据

物理删除:

image.png

软删除:

image.png

Gorm提供了gorm.DeletedAt用于帮助用户实现软删除

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

使用Unscoped可以查询到被软删除的数据。

(7)Gorm事务

Gorm提供了Tansaction方法用于自动提交事务,避免用户漏泄Commit、Rollback。

image.png

(8)Gorm Hook

Gorm提供了CURD的Hook能力。

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

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

image.png

(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生态

image.png

2、Kitex

(1)安装Kitex代码生成工具

image.png

(2)定义IDL

使用IDL定义服务和接口。

如果我们要进行RPC,就需要知道对方的接口是什么,需要传什么参数,同时也需要知道返回值是什么样的。这时候就需要通过IDL来约定双方的协议,就像在写代码时需要调用某个函数,我们需要知道函数签名一样。

image.png

(3)Kitex生成代码

使用kitex -module example -service example echo.thrift命令生成代码。

image.png

(4)Kitex基本使用

服务默认监听8888端口

image.png

(5)Kitex Client发起请求

image.png

(6)Kitex服务注册与发现

目前Kitex的服务注册与发现已经对接了主流服务注册与发现中心,如ETCD,Nacos等。

image.png

image.png

(7)Kitex生态

image.png

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等方法用于注册路由。

image.png

  • Hertz提供了路由组的能力,支持路由分组的功能

image.png

  • Hertz提供了参数路由和通配路由,优先级为:静态路由>命名路由>通配路由

image.png

(3)Hertz参数绑定

提供了Bind、Validate、BindAndValidate函数用于参数绑定和校验。

image.png

(4)Hertz中间件

主要分为客户端中间件与服务端中间件

如何终止中间件调用链的执行:

  • c.Abort
  • c.AbortWithMsg
  • c.AbortWithStats

服务端中间件:

image.png

(5)Hertz Client

提供了HTTP Client用于帮助用户发送HTTP请求

image.png

(6)Hertz代码生成工具

Hertz提供了代码生成工具Hz,通过定义IDL文件即可生成对应的基础服务代码

image.png

(7)Hertz性能

image.png

(8)Hetz生态

image.png