这篇文章主要为大家介绍了Go框架三件套Gorm Kitex Hertz的基本用法与常见API讲解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪<BR>
目录
三件套介绍

Gorm、Kitex、Hertz的基本用法与常见的API讲解
Gorm
gorm是Golang语言中一个已经迭代数十年且功能强大、性能极好的ORM框架
ORM:Object Relational Mapping(对象关系映射),其主要作用是在编程中,把面向对象的概念跟数据库中表的概念对应起来,
简单来说,在golang中,自定义的一个结构体对应着一张表,结构体的实例则对应着表中的一条记录。
Kitex
Kitex是字节内部Golang微服务RPC框架 具有高性能、强可扩展的主要特点 支持多协议并且拥有丰富的开源扩展
Hertz
Hertz是字节内部的Http框架 参考了其他开源框架的优势 结合字节跳动内部的需求 具有高可用、高性能、高扩展性的特点
三件套使用
Gorm
该部分笔记主要参考:gorm.io/zh_CN/docs
声明模型
模型定义
模型是标准的 struct,由 Go 的基本数据类型、实现了 Scanner 和 Valuer 接口的自定义类型及其指针或别名组成
1 2 3 4 5 6 7 8 9 10 11 |
typeUser 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.Model
GORM 定义一个 gorm.Model 结构体,其包括字段 ID、CreatedAt、UpdatedAt、DeletedAt
1 2 3 4 5 6 7 |
// gorm.Model 的定义 typeModel struct{ ID uint `gorm:"primaryKey"` CreatedAt time.Time UpdatedAt time.Time DeletedAt gorm.DeletedAt `gorm:"index"` } |
还可以将它嵌入到结构体中,以包含这几个字段,例如:
1 2 3 4 5 6 7 8 9 10 11 12 |
typeUser struct{ gorm.Model Name string } // 等效于 typeUser struct{ ID uint `gorm:"primaryKey"` CreatedAt time.Time UpdatedAt time.Time DeletedAt gorm.DeletedAt `gorm:"index"` Name string } |
连接到数据库
GORM 官方支持的数据库类型有: MySQL, PostgreSQL, SQlite, SQL Server
MySQL
1 2 3 4 5 6 7 8 9 |
import( "gorm.io/driver/mysql" "gorm.io/gorm" ) funcmain() { // 参考 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{}) } |
注意: 想要正确的处理 time.Time ,您需要带上 parseTime 参数, 要支持完整的 UTF-8 编码,您需要将 charset=utf8 更改为 charset=utf8mb4
使用现有数据库连接
GORM 允许通过一个现有的数据库连接来初始化 *gorm.DB
1 2 3 4 5 6 7 8 9 |
import( "database/sql" "gorm.io/driver/mysql" "gorm.io/gorm" ) sqlDB, err := sql.Open("mysql", "mydb_dsn") gormDB, err := gorm.Open(mysql.New(mysql.Config{ Conn: sqlDB, }), &gorm.Config{}) |
CRUD接口
创建记录
1 2 3 4 5 |
user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()} result := db.Create(&user) // 通过数据的指针来创建 user.ID // 返回插入数据的主键 result.Error // 返回 error result.RowsAffected // 返回插入记录的条数 |
批量插入
将切片数据传递给 Create 方法,GORM 将生成一个单一的 SQL 语句来插入所有数据,并回填主键的值,钩子方法也会被调用。
1 2 3 4 5 |
var users= []User{ {Name: "jinzhu1"}, {Name: "jinzhu2"}, {Name: "jinzhu3"}} DB.Create(&users) for_, user := rangeusers { user.ID // 1,2,3 } |
通过Map数据类型创建记录
GORM 支持根据 map[string]interface{} 和 []map[string]interface{}{} 创建记录
1 2 3 4 5 6 7 8 |
DB.Model(&User{}).Create(map[string]interface{}{ "Name": "jinzhu", "Age": 18, }) // 根据 `[]map[string]interface{}{}` 批量插入 DB.Model(&User{}).Create([]map[string]interface{}{ {"Name": "jinzhu_1", "Age": 18}, {"Name": "jinzhu_2", "Age": 20}, }) |
查询
检索单个对象
GORM 提供了 First、Take、Last 方法,以便从数据库中检索单个对象。当查询数据库时它添加了 LIMIT 1 条件,且没有找到记录时,它会返回 ErrRecordNotFound 错误
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// 获取第一条记录(主键升序) db.First(&user) // SELECT * FROM users ORDER BY id LIMIT 1; // 获取一条记录,没有指定排序字段 db.Take(&user) // SELECT * FROM users LIMIT 1; // 获取最后一条记录(主键降序) db.Last(&user) // SELECT * FROM users ORDER BY id DESC LIMIT 1; result := db.First(&user) result.RowsAffected // 返回找到的记录数 result.Error // returns error // 检查 ErrRecordNotFound 错误 errors.Is(result.Error, gorm.ErrRecordNotFound) |
First、Last 方法会根据主键查找到第一个、最后一个记录, 它仅在通过 struct 或提供 model 值进行查询时才起作用。如果 model 类型没有定义主键,则按第一个字段排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
var userUser // 可以 DB.First(&user) // SELECT * FROM `users` ORDER BY `users`.`id` LIMIT 1 // 可以 result := map[string]interface{}{} DB.Model(&User{}).First(&result) // SELECT * FROM `users` ORDER BY `users`.`id` LIMIT 1 // 不行 result := map[string]interface{}{} DB.Table("users").First(&result) // 但可以配合 Take 使用 result := map[string]interface{}{} DB.Table("users").Take(&result) // 根据第一个字段排序 typeLanguage struct{ Code string Name string } DB.First(&Language{}) // SELECT * FROM `languages` ORDER BY `languages`.`code` LIMIT 1 |
检索对象
1 2 3 4 5 |
// 获取全部记录 result := db.Find(&users) // SELECT * FROM users; result.RowsAffected // 返回找到的记录数,相当于 `len(users)` result.Error // returns error |
条件查询
String条件
1 2 3 4 5 |