字段构建器
SchemaBuilder、FieldBuilder、字段类型、索引、隐藏字段、乐观锁和模型级配置参考。
Oro 不使用 ORM tag 描述数据库结构。模型通过 Define 显式定义表结构,Go 字段负责承载业务数据。
type Product struct {
oro.Model
Code string
Price uint
Status string
}
func (Product) Define(s *oro.SchemaBuilder) {
s.Table("products")
s.Field("Code").String().Size(64).Unique()
s.Field("Price").Uint().Default(0)
s.Field("Status").String().Default("active").Index()
}
SchemaBuilder
| 方法 | 用途 |
|---|---|
Table(name) |
设置逻辑表名 |
Connection(name) |
设置模型默认连接 |
Shard(group, fields...) |
设置模型分片组和分片字段 |
Field(name) |
获取字段构建器,name 是 Go 字段名 |
Index(name, fields...) |
定义组合普通索引 |
Unique(name, fields...) |
定义组合唯一索引 |
FullText(name, fields...) |
定义组合全文索引 |
Field(name) 使用 Go 字段名。没有设置 Column 时,Oro 自动把 Go 字段名转为 snake_case 列名。
s.Field("CategoryID").UnsignedBigInt().Column("category_id")
基础类型
| 方法 | 逻辑类型 | 典型用途 |
|---|---|---|
String() |
string | 短文本 |
Text() |
text | 长文本 |
Bool() |
bool | 布尔值 |
Int() |
int | 有符号整数 |
BigInt() |
int64 | 大整数 |
Uint() / UnsignedInt() |
uint | 无符号整数 |
UnsignedBigInt() |
uint64 | 无符号大整数 |
Decimal(precision, scale) |
decimal | 金额、精度数值 |
Float() |
float | 浮点数 |
Double() |
double | 双精度浮点 |
Binary() |
binary | 二进制数据 |
JSON() |
json | JSON 字段 |
UUID() |
uuid | UUID |
Timestamp() |
time.Time | 时间戳 |
Date() |
date | 日期 |
Time() |
time | 时间 |
语义类型
语义类型会映射为各数据库最合适的列类型,便于跨库保持统一定义。
| 方法 | 用途 |
|---|---|
Enum(values...) |
枚举值 |
Email() |
邮箱 |
URL() |
URL |
IP() |
IP 地址 |
MAC() |
MAC 地址 |
Phone() |
电话 |
Slug() |
slug |
Color() |
颜色值 |
StringArray() |
字符串数组 |
IntArray() |
整数数组 |
Point() |
坐标点 |
语义类型不是验证器。应用层仍应做输入校验。
字段属性
| 方法 | 用途 |
|---|---|
Column(name) |
设置数据库列名 |
Size(size) |
设置长度 |
NotNull() |
设置非空 |
Nullable() |
设置可空 |
Default(value) |
设置数据库默认值 |
DefaultExpr(expr) |
设置数据库默认表达式 |
Comment(text) |
设置字段注释 |
Primary() |
设置主键 |
Ignore() |
ORM 完全忽略字段 |
Virtual() |
查询/输出虚拟字段,不参与同步 |
Hidden() |
序列化时默认隐藏 |
OptimisticLock() |
标记乐观锁字段 |
SoftDelete() |
标记可空时间字段为软删除字段 |
示例:
func (User) Define(s *oro.SchemaBuilder) {
s.Field("Email").Email().Size(191).Unique()
s.Field("Password").String().Size(255).Hidden()
s.Field("Version").UnsignedBigInt().Default(1).OptimisticLock()
s.Field("RemovedAt").Column("removed_at").SoftDelete()
s.Field("Profile").JSON().Nullable()
s.Field("Score").Decimal(12, 2).Default("0.00")
}
约定软删除字段优先嵌入 extensions/softdelete 的 softdelete.SoftDeleteFields,默认字段是 DeletedAt,列名是 deleted_at。只有自定义字段名时才需要 SoftDelete()。
字段备注:
func (Product) Define(s *oro.SchemaBuilder) {
s.Field("Code").String().Size(64).Comment("商品编码")
s.Field("Price").Uint().Comment("销售价格,单位分")
}
Comment 会进入模型结构元数据,并在驱动支持时同步到数据库:
| 驱动 | 行为 |
|---|---|
| MySQL | 在列定义里生成 comment '...' |
| PostgreSQL | 额外生成 comment on column ... is '...' |
| SQLite | SQLite 没有原生列备注,保留在 ORM 元数据中,不生成 DDL |
索引
字段级索引:
s.Field("Code").String().Unique()
s.Field("Status").String().Index()
s.Field("Title").String().FullText()
指定索引名:
s.Field("Code").String().Unique("products_code_unique")
组合索引:
s.Index("orders_tenant_status_idx", "TenantID", "Status")
s.Unique("users_email_app_unique", "Email", "AppID")
s.FullText("articles_search_fulltext", "Title", "Content")
组合索引里的字段名仍然是 Go 字段名。
可空字段
推荐使用 oro.Null[T] 表达数据库 NULL,避免到处解引用指针。
type Product struct {
oro.Model
Stock oro.Null[int]
}
func (Product) Define(s *oro.SchemaBuilder) {
s.Field("Stock").Int().Nullable()
}
oro.Null[T] 能区分有效值和空值,并支持 JSON 序列化。
字段定义规则
Define是模型结构的唯一来源;- tag 只用于 JSON 等 Go 标准序列化,不用于 ORM 结构定义;
Column只在字段名与数据库列名不一致时使用;- 同一个字段不要定义多个冲突类型;
- 删除、危险类型变更等操作由
Sync的安全策略处理。