这是我参与「第五届青训营 」伴学笔记创作活动的第 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 中钩子方法
- 支持
Preload、Joins的预加载 - 事务,嵌套事务,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 作为主键,使用结构体名的 蛇形复数 作为表名,字段名的 蛇形 作为列名,并使用 CreatedAt、UpdatedAt 字段追踪创建、更新时间
如果您遵循 GORM 的约定,您就可以少写的配置、代码。 如果约定不符合您的实际要求,GORM 允许你配置它们
gorm.Model
GORM 定义一个 gorm.Model 结构体,其包括字段 ID、CreatedAt、UpdatedAt、DeletedAt
// 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 风格
连接到数据库
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 框架,在设计之初参考了其他开源框架 fasthttp、gin、echo 的优势, 并结合字节跳动内部的需求,使其具有高易用性、高性能、高扩展性等特点,目前在字节跳动内部已广泛使用。 如今越来越多的微服务选择使用 Golang,如果对微服务性能有要求,又希望框架能够充分满足内部的可定制化需求,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 提供了
GET、POST、PUT、DELETE、ANY等方法用于注册路由。 - Hertz 提供了路由分组的功能
- Hertz 支持丰富的路由类型用于实现复杂的功能,包括静态路由、参数路由、通配路由。路由的优先级:
静态路由>命名路由>通配路由
- Hertz 提供了
-
Hertz参数绑定
- 参数绑定优先级: 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…