Go框架三件套基本使用 | 青训营笔记

134 阅读6分钟

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

一.课程主要内容

  • Gorm(ORM框架)
  • Hertz(Web框架)
  • Kitex(RPC框架)

二.详细知识点介绍

Gorm (ORM框架)

Gorm : The fantastic ORM library for Golang aims to be developer friendly.

特性:

  • 全功能 ORM
  • 关联 (Has One,Has Many,Belongs To,Many To Many,多态,单表继承)
  • Create,Save,Update,Delete,Find 中钩子方法
  • 支持 PreloadJoins 的预加载
  • 事务,嵌套事务,Save Point,Rollback To Saved Point
  • Context、预编译模式、DryRun 模式
  • 批量插入,FindInBatches,Find/Create with Map,使用 SQL 表达式、Context Valuer 进行 CRUD
  • SQL 构建器,Upsert,数据库锁,Optimizer/Index/Comment Hint,命名参数,子查询
  • 复合主键,索引,约束
  • Auto Migration
  • 自定义 Logger
  • 灵活的可扩展插件 API:Database Resolver(多数据库,读写分离)、Prometheus…
  • 每个特性都经过了测试的重重考验
  • 开发者友好

安装(mysql驱动)

go get -u gorm.io/gorm  
go get -u gorm.io/driver/mysql

声明模型

模型定义

模型是标准的 struct,由 Go 的基本数据类型、实现了 Scanner 和 Valuer 接口的自定义类型及其指针或别名组成

例如:

type User struct {
  ID           uint
  Name         string
  Email        *string
  Age          uint8
  Birthday     *time.Time
  MemberNumber sql.NullString
  ActivatedAt  sql.NullTime
  CreatedAt    time.Time
  UpdatedAt    time.Time
}

约定

GORM 倾向于约定优于配置 默认情况下,GORM 使用 ID 作为主键,使用结构体名的 蛇形复数 作为表名,字段名的 蛇形 作为列名,并使用 CreatedAtUpdatedAt 字段追踪创建、更新时间

如果您遵循 GORM 的约定,您就可以少写的配置、代码。 如果约定不符合您的实际要求,GORM 允许你配置它们

gorm.Model

GORM 定义一个 gorm.Model 结构体,其包括字段 IDCreatedAtUpdatedAtDeletedAt

// gorm.Model 的定义
type Model struct {
  ID        uint           `gorm:"primaryKey"`
  CreatedAt time.Time
  UpdatedAt time.Time
  DeletedAt gorm.DeletedAt `gorm:"index"`
}

您可以将它嵌入到您的结构体中,以包含这几个字段,详情请参考 嵌入结构体

字段标签

声明 model 时,tag 是可选的,GORM 支持以下 tag: tag 名大小写不敏感,但建议使用 camelCase 风格

image.png

image.png

连接到数据库

GORM 官方支持的数据库类型有: MySQL, PostgreSQL, SQlite, SQL Server

连接到Mysql数据库

Mysql

import (   "gorm.io/driver/mysql"   "gorm.io/gorm" )  
func main() {   
   // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情   
   dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"   
   db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) }

MySQL 驱动程序提供了 一些高级配置 可以在初始化过程中使用,例如:

db, err := gorm.Open(mysql.New(
    mysql.Config{DSN: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8&parseTime=True&loc=Local", // DSN data source name   
    DefaultStringSize: 256, // string 类型字段的默认长度   
    DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持      DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引   
    DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列   
    SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置 }), &gorm.Config{})

常用CRUD接口

  • 新建记录
    • 创建记录
    • 用指定字段创建记录
    • 批量插入
    • 钩子方法
    • 根据Map创建
    • 关联创建
    • 定义默认值
    • 解决Upsert,Delete冲突
  • 查询
    • 检索单个对象
    • 根据主键检索
    • 检索全部对象
    • 条件查询
    • 使用结构体拼接查询字符串(and条件)
    • 内联条件
    • not or条件
    • 查询指定字段
    • 排序,limit,Offset
    • Group by,Having
    • Distinct
    • Joins以及Joins预加载
    • 自定义查询字段
  • 更新
    • 更新单列
    • 更新多个列
      • 更新非零值
      • 全部更新
    • 更新选定字段
  • 删除
    • 物理删除
    • 乱删除

Hertz (Web框架)

Hertz[həːts] 是一个 Golang 微服务 HTTP 框架,在设计之初参考了其他开源框架 fasthttpginecho 的优势, 并结合字节跳动内部的需求,使其具有高易用性、高性能、高扩展性等特点,目前在字节跳动内部已广泛使用。 如今越来越多的微服务选择使用 Golang,如果对微服务性能有要求,又希望框架能够充分满足内部的可定制化需求,Hertz 会是一个不错的选择。

image.png

  • Hertz的快速开始

  • 应用层
     负责与用户直接交互,提供丰富易用的API接口,主要包括 Server、Client 和一些其他通用抽象。Server 提供了注册 HandlerFunc、Binding、Rendering 等能力;Client 提供了调用下游和服务发现等能力;以及抽象一个 HTTP 请求所必须涉及到的请求(Request)、响应(Response)、上下文(RequestContext)、中间件(Middleware)等等。Hertz 的 Server 和 Client 都能够提供中间件这样的扩展能力。
     应用层中一个非常重要的抽象就是对 Server HandlerFunc 的抽象。早期,Hertz 路由的处理函数 (HandlerFunc)中并没有接收标准的 context.Context,我们在大量的实践过程中发现,业务方通常需要一个标准的上下文在 RPC Client 或者日志、Tracing 等组件间传递,但由于请求上下文(RequestContext)生命周期局限于一次 HTTP 请求之内,而以上提到的场景往往存在异步的传递和处理,导致如果直接传递请求上下文,会导致出现一些数据不一致的问题。为此我们做了诸多尝试,但是因为核心原因在于请求上下文(RequestContext)的生命周期无法优雅的按需延长,最终在各种设计权衡下,我们在路由的处理函数签名中增加一个标准的上下文入参,通过分离出生命周期长短各异的两个上下文的方式,从根本上解决各种因为上下文生命周期不一致导致的异常问题。

  • 路由层

    • Hertz 提供了 GETPOSTPUTDELETEANY 等方法用于注册路由。
    • Hertz 提供了路由分组的功能
    • Hertz 支持丰富的路由类型用于实现复杂的功能,包括静态路由、参数路由、通配路由。路由的优先级:静态路由 > 命名路由 > 通配路由
  • Hertz参数绑定

image.png

- 参数绑定优先级: path > form > query > cookie > header > json > raw_body
  • Hertz中间件
    • 服务端中间件:Hertz 服务端中间件是 HTTP 请求-响应周期中的一个函数,提供了一种方便的机制来检查和过滤进入应用程序的 HTTP 请求, 例如记录每个请求或者启用CORS。
    • 客户端中间件可以在请求发出之前或获取响应之后执行:
      • 中间件可以在请求发出之前执行,比如统一为请求添加签名或其他字段。
      • 中间件也可以在收到响应之后执行,比如统一修改响应结果适配业务逻辑。

Kitex(RPC框架)

  • 安装Kitex代码生成工具
  • 使用IDL定义服务与接口
  • 使用 kitex -module example -service example echo.thrift 命令生成代码
  • 服务器默认生成
  • 创建客户端发起请求
  • kitex服务注册与发现
  • kitex生态

三.Go常见开发流程

1.分析项目需求,首先将项目模块切分成一个一个相对独立的模块
2.将抽象数据模块中涉及到的实体独立出来,抽象成数据库模型
3.建立数据库,并创建相对应的索引,加快底层查询数据效率
4.建立Go项目,导入Gorm,Gen相关依赖,建立基本的Model
5.导入Hertz相关依赖,定义模块的接口方法以及路由
6.根据接口要求编写CRUD代码,返回给应用层
7.编写好各个模块的功能后,导入kitex依赖,将每个模块的服务与接口写入IDL文件中
8.项目部署

注:各个过程都需要包含单元测试,单元测试是一个程序稳定性的基石

四.引用参考

gorm.io/zh_CN/docs/… juejin.cn/post/711195… www.cloudwego.io/zh/docs/kit… juejin.cn/post/718888…