Skip to content

GORM 数据访问公共设施:分页查询、逻辑删除、审计字段自动填充。仓库层唯一直接碰 gorm 的地方,service 拿到的是 model 不感知 SQL。写 CRUD 前先读 /crud-guide/repository

关键导出

  • PageQuery struct{PageNum, PageSize, OrderByColumn, IsAsc} + NewPageQuery / Num() / Size() / Offset() / Paginate() (Scope) / OrderBy() (clause.OrderBy, error) / HasOrder()
  • PageResult[T] struct{Total int64; Rows []T} + Page(rows, total) / PageOf(rows) / EmptyPage[T]()
  • SelectPage[T](db, q, dest *[]T) (PageResult[T], error) / SelectPageCtx[T](ctx, db, q, dest)
  • LogicDelete struct{DelFlag}(嵌入即获逻辑删除,查/改自动 del_flag='0',删改写为 UPDATE SET del_flag='1'Unscoped() 绕过)
  • AuditUser struct{UserID, DeptID} / WithAuditUser(ctx, u) / AuditUserFrom(ctx) / RegisterAuditCallbacks(db)
  • 常量 FlagNotDeleted="0" / FlagDeleted="1" / DefaultPageSize=10 / MaxPageSize=500 / AuditDefaultUserID=-1
  • 错误 ErrInvalidOrderBy

典型用法

go
// internal/system/service/client_service.go:70
repository.NewClientRepository(database.DB()).SelectPageList(ctx, q, page)

// 模型嵌入逻辑删除
type SysUser struct {
    // ...
    repository.LogicDelete
}

坑/约定

WARNING

  • SelectPage 先 Count 再 Find,用 db.Session(&gorm.Session{}) 克隆 statement 避免 SELECT count(*) 污染 Find。
  • dest 常是 VO 故不能拿 dest 反推表名(会打到不存在的表并丢逻辑删除条件)。
  • 排序列名用正则白名单防注入(列名无法参数化);OrderByColumn 支持驼峰自动转下划线。
  • LogicDeletedefault:0 必须保留(否则插入零值写空串,del_flag='0' 查询永远匹配不上)。
  • RegisterAuditCallbacksdatabase.New 内强制调用,审计身份靠 WithAuditUser 经 ctx 接力(回调只拿得到 *gorm.DB );更新回调用 SetColumnUpdates(map) 的 Dest 是 map,逐行反射覆盖不到)。 :::

相关页:/crud-guide/repository/pkg-reference/config-database-redis/conventions/naming

基于 MIT 协议开源