简体   繁体   English

如何在gorm model中传递动态表名

[英]How to pass dynamic table name in gorm model

I am using Gorm ORM for my current application.我正在为我当前的应用程序使用Gorm ORM。 I have one model correspondents to many tables with identical table structures(ie column name and type).我有一个 model 对应于许多具有相同表结构(即列名和类型)的表。 So my requirement how can I change the table name dynamically while doing the query.所以我的要求是如何在查询时动态更改表名。

For eg例如

I have product model like Product.go我有产品 model 像 Product.go

type Product struct{
  ID int
  Name strig
  Quantity int
}

And we have different products like shirts, jeans and so on and we have same tables like shirts, jeans.我们有不同的产品,如衬衫、牛仔裤等,我们有相同的桌子,如衬衫、牛仔裤。

Now I wanted to query the product as per name of the product how can we do that also want to have table created through migrations.现在我想根据产品名称查询产品,我们怎么能做到这一点,也希望通过迁移创建表。 But there is only One model than how can we run use Automigrate feature with Gorm.但是只有一个 model 比我们如何运行与 Gorm 一起使用 Automigrate 功能。

Updated for GORM v2为 GORM v2 更新

DEPRECATED: TableName will not allow dynamic table name anymore, its result will be cached for future uses.已弃用: TableName将不再允许动态表名,其结果将被缓存以备将来使用。

There is a much easier way to create several tables using the same struct:有一种更简单的方法可以使用相同的结构创建多个表:

// Create table `shirts` & `jeans` with the same fields as in struct Product
db.Table("shirts").AutoMigrate(&Product{})
db.Table("jeans").AutoMigrate(&Product{})

// Query data from those tables
var shirts []Product
var jeans []Product
db.Table("shirts").Find(&shirts)
db.Table("jeans").Where("quantity > 0").Find(&shirts)

But, now on the second thought, I would suggest using the embedded struct so that you won't have to call Table in every query and you can also have additional fields per model while still sharing the same table structure.但是,现在再考虑一下,我建议使用嵌入式结构,这样您就不必在每个查询中调用Table并且您还可以在每个 model 中拥有额外的字段,同时仍然共享相同的表结构。

type ProductBase struct {
  ID int
  Name strig
  Quantity int
}

type Shirt struct {
  ProductBase
  NeckType string
}

type Jean struct {
  ProductBase
  Ripped bool
}

db.AutoMigrate(&Shirt{}, &Jean{})

shirt, jeans := Shirt{}, make([]Jean, 0)
db.Where("neck_type = ?", "Mandarin Collar").Last(&shirt)
db.Where("ripped").Find(&jeans)

Old answer for GORM v1 GORM v1 的旧答案

You're almost there by using table field inside the struct:通过使用结构内的table字段,您几乎就在那里:

type Product struct{
  ID int
  Name strig
  Quantity int

  // private field, ignored from gorm
  table string `gorm:"-"`
}

func (p Product) TableName() string {
  // double check here, make sure the table does exist!!
  if p.table != "" {
    return p.table
  }
  return "products" // default table name
}

// for the AutoMigrate
db.AutoMigrate(&Product{table: "jeans"}, &Product{table: "skirts"}, &Product{})

// to do the query
prod := Product{table: "jeans"}
db.Where("quantity > 0").First(&prod)

Unfortunately, that does not work with db.Find() when you need to query for multiple records... The workaround is to specify your table before doing the query不幸的是,当您需要查询多条记录时,这不适用于db.Find() ... 解决方法是在执行查询之前指定您的表

prods := []*Product{}
db.Table("jeans").Where("quantity > 0").Find(&prods)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM