OOro

配置

Config、连接、连接池、日志、超时、扩展和分片配置。

Config 结构

下面是常用配置字段:

type Config struct {
    Default     string
    Connections map[string]ConnectionConfig
    TablePrefix string
    Location    *time.Location
    Pool        PoolConfig
    Shards      map[string]ShardConfig
    Cache       CacheStore
    Extensions  []Extension
    Logger      Logger
    LogLevel    LogLevel
    Timeout     TimeoutConfig
    Retry       RetryConfig
}

关键规则:所有数据库驱动都放在 Connections 下。

时间时区

db, err := oro.Open(oro.Config{
    Location: time.FixedZone("CST", 8*60*60),
})

Oro 所有 time.Time 都以 UTC 写入数据库。包括自动维护的 CreatedAt / UpdatedAt / 软删除时间、用户传入的时间字段,以及查询条件里的 时间参数。

读出数据时,Oro 会把 time.Time 转换到 Config.Location。如果不设置 Location,默认使用 time.UTC

其他高级字段:

字段 用途
Location 读出 time.Time 时转换到的时区,默认 time.UTC
Factory 替换内部组件工厂,适合测试或深度扩展
SlowQueryThreshold 慢查询阈值
LogArgs 是否在日志中输出 SQL 参数
AllowRawMultiStatement 是否允许 Raw 执行多语句 SQL
SkipDefaultTransaction 跳过默认写事务,偏向吞吐;需要业务自己评估一致性
Batch 批量创建、upsert、关系写入和读取批量大小
StatementCache prepared statement 缓存配置
SQLCache ORM 内部 SQL 编译缓存配置
ScanCache ORM 内部结构体扫描计划缓存配置

表前缀

db, err := oro.Open(oro.Config{
    TablePrefix: "tenant_",
})

TablePrefix 在 SQL 编译前把逻辑表名解析为物理表名。

  • s.Table("products") 会同步和查询 tenant_products
  • db.Table("products") 同样查询 tenant_products
  • 已经带前缀的表名不会重复添加前缀。
  • 带命名空间的表名只处理最后一段,shop.products 会变成 shop.tenant_products
  • Raw SQL 不会被改写;拼接原生 SQL 时使用 db.TableName("products")
rows, err := db.Raw("select * from "+db.TableName("products")).Get(ctx)

连接

type ConnectionConfig struct {
    Driver oro.Driver
    Reads  []oro.Driver
    Pool   *oro.PoolConfig
}
  • Driver 是主连接;
  • Reads 是读库;
  • Pool 覆盖全局连接池配置。

连接池

Pool: oro.PoolConfig{
    MaxOpenConns:    20,
    MaxIdleConns:    10,
    ConnMaxLifetime: time.Hour,
    ConnMaxIdleTime: 10 * time.Minute,
    PingOnOpen:      true,
}

全局连接池应用到所有连接,单连接可覆盖。

日志

db, err := oro.Open(oro.Config{
    Logger:   myLogger,
    LogLevel: oro.LogLevelInfo,
})

ORM 只定义小接口,不强制应用使用某个日志库。

超时和重试

db, err := oro.Open(oro.Config{
    Timeout: oro.TimeoutConfig{
        Query:       5 * time.Second,
        Transaction: 10 * time.Second,
    },
    Retry: oro.RetryConfig{
        ReadAttempts:       2,
        TxDeadlockAttempts: 3,
    },
})

单次查询也可以覆盖超时:

rows, err := db.Use[Product]().Timeout(2 * time.Second).Get(ctx)

扩展

Extensions: []oro.Extension{
    tenant.Extension(tenant.Fields("TenantID", "AppID")),
}

可选能力由扩展包提供,不放进核心 ORM。参考 扩展包Tenant 租户扩展

分片

Shards: map[string]oro.ShardConfig{
    "orders": {
        Connections: []string{"orders_0", "orders_1"},
        Strategy:    oro.ModShard("TenantID"),
    },
}

ModShard 根据字段值对 Connections 长度取模,不需要额外传分片数量。

模型在 Define 中启用分片:

func (Order) Define(s *oro.SchemaBuilder) {
    s.Shard("orders", "TenantID")
}
编辑此页