扩展机制
通过 Config.Extensions 安装可选 Oro 扩展,不把所有能力塞进核心 ORM。
扩展是可选包,用来增加横切能力或更高层的数据结构,同时保持 Oro 核心轻量。
db, err := oro.Open(oro.Config{
Connections: map[string]oro.ConnectionConfig{
"default": {Driver: sqlite.Open("app.db")},
},
Extensions: []oro.Extension{
tenant.Extension(tenant.Fields("TenantID")),
nestedset.Extension(),
},
})
扩展能做什么
扩展可以接入明确的生命周期点:
| Hook | 用途 |
|---|---|
Install |
校验配置或初始化状态 |
ApplyQuery |
追加查询条件,例如租户过滤 |
ApplyWrite |
注入或校验写入值 |
ApplyConnection |
把查询路由到指定连接 |
ShardValues |
提供分片路由值 |
CacheKeyValues |
把扩展状态加入自动缓存键 |
查询链 Apply
查询链扩展统一通过 db.Use[T]().Apply(...) 组合,扩展包只提供行为对象,Where、With、OrderBy、分页、聚合等查询能力仍然复用核心 ModelQuery。
products, err := db.Use[Product]().
Apply(translation.Locale("zh-CN")).
Where("Status", "online").
OrderByDesc("ID").
Get(ctx)
children, err := db.Use[Category]().
Apply(nestedset.DescendantsOf(root), nestedset.DefaultOrder()).
Where("Status", "enabled").
Get(ctx)
结构性业务服务仍保留在扩展包里,例如树形创建、移动、删除使用 nestedset.Use[Category](db),因为这些不是普通查询条件。
扩展字段嵌入
部分扩展需要模型字段。Oro 通过标记过的匿名字段结构体支持这一点:
type Category struct {
oro.Model
nestedset.NodeFields
Name string
}
nestedset.NodeFields 实现了 Oro 的嵌入字段标记,schema parser 会把其中导出的字段当成模型字段处理。这样扩展字段可以复用,也不需要 tag 或代码生成。
官方扩展
| Package | 用途 |
|---|---|
extensions/development |
扩展开发指南,覆盖全局 hook、apply 对象和嵌入字段 |
extensions/tenant |
租户过滤、写入注入、连接路由、分片值、缓存键值 |
extensions/softdelete |
约定软删除字段、默认隐藏已删除数据、恢复与物理删除 |
extensions/audit |
自动写入创建人、更新人、删除人,并记录审计日志 |
extensions/translation |
使用 JSON 字段保存模型翻译内容,支持默认语言与回退语言 |
extensions/metrics |
把 SQL、缓存、事务事件输出为指标样本 |
extensions/logroll |
对追加型日志单表做滚动保留 |
extensions/nestedset |
基于 ParentID、_lft、_rgt 和 Depth 的树形数据 |