大家好,
平时在用 Go 和 GORM 写业务代码时,不知道大家有没有经历过以下几个极其破坏开发体验的“痛点”:
- 脆弱的魔法字符串:写着
db.Where("age > ? AND user_name LIKE ?", 18, "%张三%"),一旦数据库字段名改了,编译期根本发现不了,直接在运行时原地爆炸。 - 连表查询的字段歧义:当你
Joins了好几张表,一旦有多张表都有id或created_at,直接给你报ambiguous column name,只能痛苦地手拼users.id。 - 恶心的事务传递:为了保证事务,不得不把
tx *gorm.DB作为参数在 Service 层和 Repo 层之间传来传去,极其破坏架构的整洁度。 - 查询条件互相污染:复用同一个基础查询构建器时,底层的 Slice 被
append污染,导致派生查询带上了莫名其妙的 WHERE 条件。
为了彻底解决这些痛点,我把团队内部沉淀的脚手架剥离、重构,开源了这个纯粹的通用依赖库:GORM Query。
🔗 开源地址:github.com/im-wmkong/g…
✨ 这个库能帮你做什么?
1. 极致的强类型查询(告别魔法字符串)
只需要在现有的 Model 上加一行注释,内置的代码生成器就能自动生成强类型的属性字典(完美兼容 gorm.Model)。
以前你这样写:
db.Where("status = ? AND age >= ?", 1, 18).Find(&users)
现在你可以这样写(享受 IDE 的完美代码提示,彻底消灭拼写错误):
qb := query.New().Where(
model.UserProps.Status.Eq(1),
model.UserProps.Age.Gte(18),
)
qb.Apply(db).Find(&users)
2. 丝滑解决 JOIN 字段歧义
生成的属性自带 .Alias() 方法,利用底层私有常量拼接,保证幂等性的同时,极其优雅地解决连表前缀问题:
// 直接生成带前缀的 SQL: u.age > 18 AND p.city = 'Beijing'
qb := query.New().Joins("JOIN profiles p ON u.id = p.user_id").Where(
model.UserProps.Alias("u").Age.Gt(18),
model.ProfileProps.Alias("p").City.Eq("Beijing"),
)
3. 隐式上下文事务(让 Service 与 Repo 彻底解耦)
库内置了基于 context.Context 的事务管理器和 repo.BaseRepository[T] 泛型基类。
配合依赖注入,你的 Service 层可以保持极致的干净,一行 DB 相关的代码都不用写:
// 业务代码完全不需要知道底层 gorm.DB 的存在
func (s *UserService) CreateUserAndProfile(ctx context.Context, user *model.User, profile *model.Profile) error {
// 一键开启事务,向下文透传
return s.tm.Transaction(ctx, func(txCtx context.Context) error {
// 底层的 BaseRepository 会自动感知 txCtx 并使用事务连接!
if err := s.userRepo.Create(txCtx, user); err != nil {
return err
}
profile.UserID = user.ID
// 如果这里失败,上面的 Create 会自动回滚
if err := s.profileRepo.Create(txCtx, profile); err != nil {
return err
}
return nil
})
}
4. 安全的查询克隆 (防污染)
提供 .Clone() 方法深度拷贝查询条件,基础查询随心复用:
baseQuery := query.New().Where(UserProps.Status.Eq(1))
adultsQuery := baseQuery.Clone().Where(UserProps.Age.Gte(18))
minorsQuery := baseQuery.Clone().Where(UserProps.Age.Lt(18)) // 安全独立,互不污染
🛠️ 如何快速体验?
只需要两步:
第一步:引入库并添加生成指令
//go:generate go run [github.com/im-wmkong/gorm-query/cmd/gen-props@latest](https://github.com/im-wmkong/gorm-query/cmd/gen-props@latest) -type=User
第二步:执行生成命令
在终端运行 go generate ./...,然后就可以开始享受丝滑的编码体验了!
如果你也追求代码的优雅与整洁,欢迎去 GitHub 看看源码。如果觉得这个设计思路对你的日常开发有帮助,求个 Star ⭐️ 支持一下!也极其欢迎各种 Issue 和 PR 一起共建。