GORM 默认把结构体名转为蛇形复数作为表名。但实际项目中,表名规则各不相同,GORM 提供了多种自定义方式。
type User struct {} // → users
type OrderItem struct {} // → order_items
type Person struct {} // → people
规则:驼峰转蛇形,再加复数。
实现 TableName 方法自定义表名:
type User struct {
ID uint
Name string
}
func (User) TableName() string {
return "app_users"
}
这是最常用的方式,优先级最高。
根据条件返回不同表名:
type Order struct {
ID uint
UserID uint
Amount float64
}
func (o Order) TableName() string {
// 按用户分表
if o.UserID > 0 {
return fmt.Sprintf("orders_%d", o.UserID%10)
}
return "orders"
}
查询时临时指定表名:
// 使用 Table 方法
db.Table("admin_users").Find(&users)
// 使用 Scopes
func WithTable(name string) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Table(name)
}
}
db.Scopes(WithTable("temp_users")).Find(&users)
配置全局命名策略:
import "gorm.io/gorm/schema"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
NamingStrategy: schema.NamingStrategy{
TablePrefix: "t_", // 表名前缀
SingularTable: true, // 禁用复数
NoLowerCase: false, // 是否保持原样
},
})
添加表名前缀:
NamingStrategy: schema.NamingStrategy{
TablePrefix: "t_",
}
// User → t_users
// OrderItem → t_order_items
禁用复数:
NamingStrategy: schema.NamingStrategy{
SingularTable: true,
}
// User → user
// OrderItem → order_item
完全自定义:
type CustomNamingStrategy struct {
schema.NamingStrategy
}
func (ns CustomNamingStrategy) TableName(name string) string {
// 全部转大写,加前缀
return "TBL_" + strings.ToUpper(ns.NamingStrategy.TableName(name))
}
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
NamingStrategy: CustomNamingStrategy{},
})
// User → TBL_USERS
列名也受命名策略影响:
NamingStrategy: schema.NamingStrategy{
NoLowerCase: true, // 保持原样
}
// UserName → UserName(而不是 user_name)
按时间分表:
type Log struct {
ID uint
Content string
CreatedAt time.Time
}
func (l Log) TableName() string {
// 按月分表
return "logs_" + l.CreatedAt.Format("200601")
}
// 或者查询时指定
func GetLogsByMonth(db *gorm.DB, year, month int) []Log {
var logs []Log
tableName := fmt.Sprintf("logs_%d%02d", year, month)
db.Table(tableName).Find(&logs)
return logs
}
按租户分表:
var currentTenant string
func SetTenant(tenant string) {
currentTenant = tenant
}
func (User) TableName() string {
return currentTenant + "_users"
}
PostgreSQL 的 schema:
func (User) TableName() string {
return "public.users" // public schema
}
func (Order) TableName() string {
return "orders.orders" // orders schema
}
表名配置方式:
| 方式 | 适用场景 |
|---|---|
| 默认规则 | 简单项目,遵循约定 |
| TableName 方法 | 固定表名,优先级最高 |
| Table 方法 | 临时指定,灵活 |
| 全局策略 | 统一前缀、禁用复数 |
| 动态 TableName | 分表场景 |
建议: