OOro

Oro ORM

Go 1.27+

代码即查询,所见即所得

面向 Go 的泛型 ORM —— 语义化条件、透明 SQL、零代码生成。

  • 人性化语义
  • 零代码生成
  • 无循环依赖
  • 非黑盒
go get github.com/duxweb/oro
product.go
// 模型就是普通的 Go struct
type Product struct {
    oro.Model
    Code  string
    Price uint
}

// 像说话一样写条件
list, _ := db.Use[Product]().
    Where(
        oro.Field("Price").Gte(100),
        oro.Field("Code").Like("P%"),
    ).
    Get(ctx)
核心设计

让 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]()

一行 go get 即可开始

打开数据库、注册模型、同步结构,几分钟内跑通你的第一条类型化查询。