核心设计
让 ORM 像 Go 代码一样直观
查询看得懂,模型不用生成,关联不制造循环依赖,返回值也有明确类型边界。
查询可读
字段、比较和组合条件都有明确方法。复杂条件不用埋进 SQL 字符串,审查时能直接看出查询意图。
db.Use[Product]().Where(oro.Field("Price").Gte(100))
db.Use[Product]().Where(oro.Field("Code").Like("A%"))无需生成
模型就是普通 Go 结构体,查询直接使用泛型入口。没有生成器、client 文件和额外构建步骤。
db.Register(Product{})
db.Use[Product]().Create(ctx, product)关系不循环
关联定义在方法里,不把关联对象塞进结构体字段。模型拆到多个包后,也能避开 import cycle。
article.Cover().One[Image]()
db.Use[Article]().With(Article{}.Cover())类型边界清晰
模型查询返回具体类型,动态写入使用 Map,原生 SQL 走 Raw。需要灵活的地方也有明确边界。
db.Use[Product]().First(ctx) // *Product
db.Table("products").First(ctx) // oro.Map设计取舍
把 ORM 的边界写在代码表面
Oro 不靠生成器隐藏复杂度,也不把结构配置塞进 tag 字符串。模型、表、原生 SQL 是三条明确入口:业务代码用模型,动态场景用表,复杂查询直接 Raw。
- 字段结构走
Define,不用在 tag 里拼配置。 - 写入字段显式表达,不猜零值。
- 关系放在方法里,减少模块拆包后的 import cycle。
func (Product) Define(s *oro.SchemaBuilder) {
s.Table("products")
s.Field("Code").String().Unique()
s.Field("Price").Uint().Default(0)
}
db.Use[Product]() // *Product / []Product
db.Table("products") // oro.Map
db.Raw("select ...") // Map or MapTo[T]()文档
从这里开始
按这个顺序读,能最快理解 Oro 的使用方式:先跑通,再定义模型,最后掌握条件组合。