Files
easygoadmin-wiki/EasyGoAdmin_Gin_AntdVue/zh/guide/repository.md
T
2026-10-25 17:24:27 +08:00

106 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 3.4 数据访问层(repository)
:::tip 概述
仓储层做一件事:给 service 一个安全的数据库入口。**铁律:禁止裸用 `*gorm.DB`**——统一经 `repository.NewXxxRepo().Ctx(ctx)` 访问,软删过滤与租户隔离自动注入。
:::
## 标准结构
```go
// internal/repository/example.go
package repository
import (
"context"
"gorm.io/gorm"
)
// ExampleRepo 案例演示仓储
type ExampleRepo struct {
Base
}
// NewExampleRepo 构造案例演示仓储(表名 = gin_ + 模块名)
func NewExampleRepo() *ExampleRepo {
return &ExampleRepo{Base: NewBase("gin_example")}
}
// Ctx 带 ctx 的查询入口
func (r *ExampleRepo) Ctx(ctx context.Context) *gorm.DB {
return r.Base.Ctx(ctx)
}
```
就这么短——结构、构造、Ctx 三段是每个仓储的固定模板,自定义查询方法按需追加在同文件内。关联表(user_role / role_menu)同样建仓储。
## Base 提供的能力
`Ctx(ctx)` 返回的 `*gorm.DB` 已自动注入:
| 注入项 | 条件 |
|---|---|
| `del_flag = 0` | 所有表——已软删行对查询不可见 |
| `tenant_id IN (0, 自身租户)` | 仅租户白名单表且当前身份非平台级(超管)时 |
Base 附带的便捷方法:
```go
// 软删除(业务删除统一入口,UPDATE del_flag=1)
repo.SoftDelete(ctx, "id", id)
repo.SoftDeleteByID(ctx, id)
// 存在性判断(软删/租户已过滤)
ok, err := repo.ExistsByCond(ctx, "name", name)
```
## GORM 查询写法要点
| 场景 | 写法 |
|---|---|
| 等值条件 | `.Where("col = ?", v)` |
| 非等值 | `.Where("id <> ?", id)` |
| IN 条件 | `.Where("col IN ?", slice)` |
| LIKE | `.Where(col+" LIKE ?", "%"+pat+"%")` |
| 指定列 | `.Select("a,b")` |
| 单行读 map | `.Take(&one)`(one 为 `map[string]any`,判空用 `gorm.ErrRecordNotFound`) |
| 多行读 | `.Find(&rows)`(`[]map[string]any` 或 `*[]*T`) |
| 计数 | `.Count(&n)`(n 为 int64) |
| map 插入 | `.Create(&d)`(d 为 `map[string]any`) |
| map 更新 | `.Where(..).Updates(d)` |
| 分页 | `.Offset((p-1)*size).Limit(size).Find(&list)` |
| 排序 | `.Order("sort, id")` |
| 结构体扫描 | Find 直接扫结构体(无 gorm 标签时按字段名蛇形映射;非列字段加 `gorm:"-"`) |
## Raw 入口(受限场景)
```go
repo.Raw(ctx) // 不注入软删/租户 Scope
```
`Raw()` 仅限**导入、字典管理、登录校验**等明确场景使用——已软删行会进入结果集、跨租户数据可见,条件完整性由使用者自行保证。常规业务查询一律走 `Ctx`。
## 事务
```go
// db.WithTrans:事务内所有 Ctx 查询自动复用事务连接
err := db.WithTrans(ctx, func(ctx context.Context) error {
if err := repoA.Ctx(ctx).Create(&d1).Error; err != nil {
return err // 返回错误自动回滚
}
return repoB.Ctx(ctx).Create(&d2).Error
})
```
事务内务必使用回调入参的 ctx(而非外层 ctx),否则拿不到事务连接。
## 编写检查清单
- [ ] 表名 `gin_` 前缀 + 模块名
- [ ] 只有 Ctx / Raw 两个查询入口,无裸 `*gorm.DB` 字段外泄
- [ ] 删除走 SoftDelete 系列,不写物理 DELETE
- [ ] Raw 使用处有注释说明场景正当性
## 下一步
→ [3.5 业务层开发(service)](/zh/guide/service.html)