开箱即用的go-zero(中)| 青训营

707 阅读4分钟

Go-zero 实战项目:blog

本文将go-zero调用数据库部分做详细讲解,并且提供两种方法,一种为model自带的,另外一种则是结合gorm实现的,给读者对两种用法做一个了解同时给予更丰富的选择。

model 层

编写 sql 文件

编写创建表的 SQL 文件 user.sql, 并在数据库中执行。 生成 model 相关代码

运行命令 goctl model mysql ddl -c -src user.sql -dir ., 会生成操作数据库的 CRDU 的代码。

此时的 model 目录:

├── user.sql # 手写
├── usermodel.go # 自动生成
└── vars.go # 自动生成

model 生成的代码注意点

  • model 这块代码使用的是拼接 SQL 语句,可能会存在 SQL 注入的风险。
  • 生成 CRUD 的代码比较初级,需要我们手动编辑 usermodel.go 文件,自己拼接业务需要的 SQL。参见 usermdel.go 中的 FindByName 方法。
  • 这里需要注意的是自带的数据库orm框架不支持主键复合,并且表的创建要符合他们的规范

rpc 调用 model 层代码的步骤

  • 编辑 etc/user.yaml 文件
Name: user.rpc
ListenOn: 127.0.0.1:8080
Etcd:
  Hosts:
  - 127.0.0.1:2379
  Key: user.rpc
# 以下为手动添加的配置
# mysql 配置
DataSource: root:1234@tcp(localhost:3306)/gozero
# 对应的表
Table: user
# redis 作为换存储
Cache:
  - Host: localhost:6379
  • 编辑 internal/config/config.go 文件
type Config struct {
// zrpc.RpcServerConf 表明继承了 rpc 服务端的配置
   zrpc.RpcServerConf
   DataSource string          // 手动代码
   Cache      cache.CacheConf // 手动代码
}
  • 编辑 internal/svc/servicecontext.go, 把 model 等依赖封装起来。

type ServiceContext struct {
   Config config.Config
   Model  model.UserModel // 手动代码
}

func NewServiceContext(c config.Config) *ServiceContext {
   return &ServiceContext{
      Config: c,
      Model:  model.NewUserModel(sqlx.NewMysql(c.DataSource), c.Cache), // 手动代码
   }
}

然后编写相应的服务就好

使用gorm连接数据库

首先l go install gorm.io/gen/tools/gentool@latest

执行gen

gentool -dsn "root:123456@tcp(192.168.1.13:3306)/bk?charset=utf8mb4&parseTime=True&loc=Local" -outPath "./bkmodel/dao/query"

然后在go mod tidy

image.png

如图为代码结构 增加Mysql配置,修改etc/user.yaml

Name: User
Host: 0.0.0.0
Port: 8888


DataSource: root:123456@tcp(192.168.1.13:3306)/bk?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai

修改tapi/internal/config/config.go

type Config struct {  
zrpc.RpcServerConf  
DataSource string
}

修改tapi/internal/svc/servicecontext.go


type ServiceContext struct {  
Config config.Config  
BkModel *query.Query  
}  
  
func NewServiceContext(c config.Config) *ServiceContext {  
db, err := gorm.Open(mysql.Open(c.DataSource), &gorm.Config{})  
//如果出错就GameOver了  
if err != nil {  
panic(err)  
}  
return &ServiceContext{  
Config: c,  
BkModel: query.Use(db),  
}  
}

然后就可以实现相应的业务逻辑了

gorm和go-zero goctl生成的优缺点

go-zero

go-zero 是一个集成了各种工程实践的 web 和 rpc 框架。它有自己的数据库操作库,特点包括:

  • 优点

    • 遵循简洁的 API 设计哲学,提供了一套简单易用的 API。
    • 提供了一些强大的功能,如自动缓存管理,提供了一种透明的方式来管理缓存和数据库之间的一致性。
    • 支持多种数据库系统(如 MySQL, Postgres, SQLite)。
    • 自带代码生成工具,可以自动生成 CRUD 操作的代码。
  • 缺点

    • 相比于 gormgo-zero 的社区规模较小,因此可能在查找问题解决方案和学习资源时会遇到一些困难。
    • 由于 go-zero 的数据库部分是与整个框架紧密集成的,因此如果你只想使用它的数据库部分可能会有些困难。

gorm

gorm 是一个完整的 Go 语言 ORM 库,它为处理对象关系映射提供了丰富的功能。

  • 优点

    • 提供了一套全面且强大的 ORM 功能,包括事务,迁移,SQL 构建,预加载,联接等。
    • 有一个庞大的社区和大量的学习资源,可以帮助你解决遇到的问题。
    • gorm 可以与任何满足 database/sql 接口的数据库驱动一起工作,支持的数据库系统非常多。
  • 缺点

    • 由于 gorm 是一个全功能的 ORM,因此其 API 可能会比 go-zero 更复杂,学习曲线可能会更陡峭。
    • gorm 不提供缓存功能,如果你需要使用缓存,则需要自己实现。

总的来说,go-zero 和 gorm 在数据库操作上各有优势,你应该根据你的项目需求和个人偏好来选择使用哪个。如果你需要一个集成度高,自动化程度高的解决方案,go-zero 可能是一个不错的选择。如果你需要更全面的 ORM 功能,或者你正在寻找一个独立的数据库库,那么 gorm 可能更适合你。

小结

本人项目使用gorm,之前也用过gorm生成的数据库,确实有缓存机制可以让代码简化不少,但是缺点就是不支持主键复合等,而上层应用依赖于底层设计的原则,不应该修改数据库,所以使用gorm,目前只用数据库,后续功能优化的时候会加入redis等。