Go 框架三件套(Web/RPC/ORM)笔记

145 阅读4分钟

Go 框架(Web/RPC/ORM)

一、三件套介绍

  • ORM 框架:GORM

    • GORM 是一个已经迭代了十多年的功能强大的 ORM 框架,拥有非常丰富的开源扩展。
    • ORM 全称是 Object Relational Mapping(对象关系映射),其主要作用是在编程中,把面向对象的概念跟数据库中表的概念对应起来。
    • GORM 支持多种数据库,如 MySQL, PostgreSQL, SQLite, SQL Server 等,并提供了简洁和灵活的 API 来操作数据库。
  • RPC 框架:Kitex

    • Kitex 由字节跳动开发,是 Golang 微服务 RPC 框架,具有高性能、强可扩展的主要特点,支持多协议并且拥有丰富的开源扩展。
    • RPC 全称是 Remote Procedure Call(远程过程调用),其主要作用是让不同的服务之间可以通过网络进行通信和数据交换。
    • Kitex 采用了模块化和插件化的设计,可以方便地定制和扩展各种功能,如服务发现、负载均衡、熔断降级、限流熔断、监控报警等。
  • HTTP 框架:Hertz

    • Hertz 是一个轻量级的 HTTP 框架,基于 net/http 包实现,提供了简单和优雅的 API 来构建 Web 应用。
    • HTTP 全称是 HyperText Transfer Protocol(超文本传输协议),其主要作用是规定了客户端和服务器之间交换信息的格式和方式。
    • Hertz 支持路由分组、中间件、模板渲染、静态文件服务、错误处理等常用的 Web 功能,并且兼容标准库中的 http.Handler 接口。

二、三件套的基础使用

  • GORM 的基础使用

    • 首先,我们需要导入 gorm 包,并使用 gorm.Open 函数来连接数据库。我们可以指定数据库的类型、地址、用户名、密码等参数。
import (
  "gorm.io/gorm"
  "gorm.io/driver/mysql"
)

func main() {
  // 连接 MySQL 数据库
  dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
  db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
  if err != nil {
    panic("failed to connect database")
  }
}
  • 然后,我们需要定义一个结构体来表示数据库中的表。我们可以使用 gorm.Model 来嵌入一些通用的字段,如 ID, CreatedAt, UpdatedAt, DeletedAt 等。我们也可以使用标签来指定字段的属性,如类型、长度、索引、外键等。
// 定义一个 User 结构体,对应 users 表
type User struct {
  gorm.Model // 嵌入通用字段
  Name string `gorm:"size:255"` // 设置字段长度为 255
  Age int `gorm:"index"` // 设置字段为索引
  Email string `gorm:"unique"` // 设置字段为唯一
  Address string `gorm:"type:varchar(100)"` // 设置字段类型为 varchar(100)
  Profile Profile `gorm:"foreignKey:UserID"` // 设置外键关联 Profile
}

// 定义一个 Profile 结构体,对应 profiles 表
type Profile struct {
  gorm.Model // 嵌入通用字段
  UserID uint // 设置外键字段
  Bio string `gorm:"size:500"` // 设置字段长度为 500
  Avatar string `gorm:"size:255"` // 设置字段长度为 255
}
  • 接下来,我们可以使用 db.AutoMigrate 函数来自动创建或更新数据库中的表。我们可以传入多个结构体参数,GORM 会根据结构体的定义来生成对应的 SQL 语句。
// 自动创建或更新 users 表和 profiles 表
err := db.AutoMigrate(&User{}, &Profile{})
if err != nil {
  panic("failed to migrate database")
}
  • 最后,我们可以使用 db.Create, db.Find, db.First, db.Update, db.Delete 等函数来对数据库进行增删改查的操作。我们可以传入结构体或切片作为参数,也可以使用链式调用来添加条件或排序等。
// 创建一个 User 记录
user := User{Name: "Alice", Age: 18, Email: "alice@example.com", Address: "New York"}
db.Create(&user)

// 查询所有的 User 记录,按照年龄降序排序
var users []User
db.Order("age desc").Find(&users)

// 查询名字为 Bob 的第一个 User 记录
var user User
db.Where("name = ?", "Bob").First(&user)

// 更新 User 记录的 Email 字段
db.Model(&user).Update("email", "bob@gmail.com")

// 删除 User 记录
db.Delete(&user)
  • Kitex 的基础使用

    • 首先,我们需要定义一个服务的接口,使用 Thrift 或 Protobuf 来描述服务的方法和参数。我们可以使用 kitex tool 来生成服务的代码。
// 定义一个 EchoService 接口,有一个 Echo 方法,接受一个 string 类型的参数,返回一个 string 类型的结果
service EchoService {
  string Echo(1:string msg)
}
# 使用 kitex tool 来生成服务的代码,-lang 指定语言为 go,-service 指定服务名为 echo
kitex -lang go -service echo echo.thrift
  • 然后,我们需要实现服务的逻辑,继承生成的服务接口,并重写对应的方法。我们可以在方法中添加自己的业务逻辑。
// 导入生成的服务包
import "echo/echo"

// 定义一个 EchoServiceImpl 结构体,实现 EchoService 接口
type EchoServiceImpl struct{}

// 实现 Echo 方法,返回参数加上 "Hello, " 的字符串
func (s *EchoServiceImpl) Echo(ctx context.Context, msg string) (string, error) {
  return "Hello, " + msg, nil
}
  • 接下来,我们需要创建一个服务端,使用 kitex.NewServer 函数来创建一个 Server 对象。我们可以传入服务的实现对象、监听的地址、日志对象等参数。
import (
  "context"
  "log"
  "net"

  "github.com/cloudwego/kitex/pkg/klog"
  "github.com/cloudwego/kitex/server"
)

func main() {
  // 创建一个 EchoServiceImpl 对象
  handler := &EchoServiceImpl{}

  // 创建一个 Server 对象,传入服务实现对象、监听地址、日志对象等参数
  srv := kitex.NewServer(
    handler,
    server.WithServiceAddr(net.JoinHostPort("0.0.0.0", "8888")),
    server.WithLogger(klog.StdLogger()),
  )

  // 启动服务端,监听请求并处理
  err := srv.Run()
  if err != nil {
    log.Fatal(err)
  }
}
  • 最后,我们需要创建一个客户端,使用 kitex.NewClient 函数来创建一个 Client 对象。我们可以传入服务接口、目标地址、日志对象等参数。
import (
  "context"
  "log"

  "github.com/cloudwego/kitex/pkg/klog"
  "github.com/cloudwego/