Go框架三件套详解
gorm:orm框架,帮助操作数据库
kitex:RPC框架,将方法抽象出来作为基础服务,提高复用性
hertz:http框架
1. GORM
1. GORM 的基础设置
在开始使用 GORM 前,需要先安装和初始化。
安装
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
初始化数据库连接
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
"log"
)
func main() {
// DSN 格式:username:password@tcp(host:port)/dbname?param=value
dsn := "root:password@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatal("Failed to connect to database:", err)
}
log.Println("Database connected successfully!")
}
2. 模型定义
在 GORM 中,模型是一个普通的 Go 结构体,通常与数据库表对应。
模型示例
type Product struct {
ID uint `gorm:"primaryKey"` // 主键字段
Code string `gorm:"size:20;unique"` // 唯一字段,长度为 20
Price uint
CreatedAt time.Time
UpdatedAt time.Time
}
模型注解(Tags)
primaryKey:指定主键字段。size:指定字符串字段的最大长度。unique:指定字段值必须唯一。autoIncrement:自动递增字段。not null:字段不能为空。
3. 数据库操作
以下是 GORM 的基本操作示例,包括创建、读取、更新和删除。
1. 创建(Create)
使用 Create 方法插入记录:
func main() {
db.Create(&Product{Code: "D42", Price: 100})
}
批量插入:
products := []Product{
{Code: "D41", Price: 50},
{Code: "D42", Price: 100},
{Code: "D43", Price: 150},
}
db.Create(&products)
2. 读取(Read)
查询单条记录
var product Product
db.First(&product, 1) // 按主键查询,返回 ID=1 的记录
db.First(&product, "code = ?", "D42") // 按条件查询
查询多条记录
var products []Product
db.Find(&products) // 查询所有记录
db.Where("price > ?", 50).Find(&products) // 按条件查询
3. 更新(Update)
更新单个字段
db.Model(&product).Update("Price", 200)
更新多个字段
通过结构体:
db.Model(&product).Updates(Product{Price: 200, Code: "F42"}) // 仅更新非零值字段
通过 map:
db.Model(&product).Updates(map[string]interface{}{"Price": 200, "Code": "F42"})
表达式更新
db.Model(&User{ID:111}).Update("ag1",gorm.Expr("age * ? + ?", 2, 100));
4. 删除(Delete)
删除单条记录
db.Delete(&product) // 根据主键删除
按条件删除
db.Where("price < ?", 100).Delete(&Product{})
4. 批量操作
GORM 支持对多条记录的批量操作。
批量更新
db.Model(&Product{}).Where("price < ?", 100).Update("Price", 150)
批量删除
db.Where("price > ?", 200).Delete(&Product{})
5. 高级功能
1. 自动迁移(AutoMigrate)
AutoMigrate 会自动创建或更新数据库表结构:
db.AutoMigrate(&Product{})
2. 事务(Transaction)
db, err := gorm.Open(mysql.Open("username:password@tcp(localhost:9910)/database?charset=utf8"),
&gorm.Config{})
if err != nil {
panic("failed to connect database")
}
tx := db.Begin() //开始事务
// 在事务中执行一些 db 操作(从这里开始,应使用'tx'而不是'db')
if err = tx.create(&User{Name:"name"}).Error; err != nil{
tx.Rollback()
// 遇到错误时回滚事务
return
}
if err = tx.Create(&User{Name: "name1"}).Error; err != nil {
tx.Rollback()
return
}
// 提交事务
tx.Commit()
Gorm提供了transaction方法,用于自动提交事务,避免用户漏写roll back和commit
err := db.Transaction(func(tx *gorm.DB) error {
if err := tx.Create(&Product{Code: "D42", Price: 100}).Error; err != nil {
return err // 回滚事务
}
if err := tx.Create(&Product{Code: "D43", Price: 200}).Error; err != nil {
return err // 回滚事务
}
return nil // 提交事务
})
if err != nil {
log.Println("Transaction failed:", err)
}
3. 关联关系(Relationships)
GORM 支持一对多、多对多等关系。
一对多关系
type User struct {
ID uint
Name string
Posts []Post // 一个用户有多个帖子
}
type Post struct {
ID uint
UserID uint
Title string
}
db.AutoMigrate(&User{}, &Post{})
查询关联关系
go复制代码var user User
db.Preload("Posts").First(&user, 1) // 预加载 Posts 关联数据
4. 钩子(Hooks)
在模型的生命周期中可以定义钩子函数,如 BeforeCreate、AfterCreate。
示例
type User struct {
ID int64
Name string 'gorm:"default:galeone"'
Age int64 'gorm:"default:18"'
}
type Email struct{
ID int64
Name string
Email string
}
func (p *Product) BeforeCreate(tx *gorm.DB) (err error) {
if p.Price <= 0 {
return errors.New("price must be greater than 0")
}
return
}
func (u *User) AfterCreate(tx *gorm.DB) (err error){
return tx.Create(&Email{ID: u.ID, Email: u.Name+ "@***.com"}).Error
}
总结
| 操作类型 | 方法 | 示例代码 |
|---|---|---|
| 创建 | Create | db.Create(&Product{}) |
| 读取 | First、Find、Where | db.Where("price > ?", 100).Find(&p) |
| 更新 | Update、Updates | db.Model(&p).Update("Price", 200) |
| 删除 | Delete | db.Delete(&p) |
| 迁移 | AutoMigrate | db.AutoMigrate(&Product{}) |
| 事务 | Transaction | db.Transaction(func(tx *gorm.DB)) |
2. Kitex
对win支持不完善。
服务注册:
服务发现:
3. Hertz
注册路由
也可以用handlle方法,自定义路由
路由分组
参数路由和通配路由
参数绑定
中间件
Hertz Client
Hertz 提供了HTTP Client用于帮助用户发送HTTP请求
Hertz 代码生成工具
Hertz提供了代码生成工具Hz,通过定义IDL文件即可生成对应的基础服务代码。
实战项目
实现功能
调用链
技术框架: