我正在尝试自动预加载模型,但是这样做很困难。
这些是我正在使用的模型:
package domain type User struct { gorm.Model Name string Car Car `gorm:"auto_preload"` Account Account `gorm:"auto_preload"` } type Car struct { gorm.Model Type int UserID uint } type Account struct { gorm.Model Powerlevel int UserID uint }
这是我正在执行的用于测试自动预加载功能的代码:
func main() { db, err := gorm.Open("sqlite3", "./data.db") if err != nil { println(err.Error()) } //Migrate the tables db.AutoMigrate(&domain.User{}) db.AutoMigrate(&domain.Car{}) db.AutoMigrate(&domain.Account{}) // Initialize our models var testUser domain.User var car = domain.Car{Type: 1994} var account = domain.Account{Powerlevel: 9001} testUser.Name = "Jim Bob" testUser.Car = car testUser.Account = account // Save the user db.Create(&testUser) // Get a new user var newUser domain.User db.First(&newUser) println(newUser.Name) println(newUser.Car.Type) println(newUser.Account.Powerlevel) // Explicitly preload db.Preload("Car").First(&newUser) db.Preload("Account").First(&newUser) println(newUser.Name) println(newUser.Car.Type) println(newUser.Account.Powerlevel) }
这两个打印的输出是:
Jim Bob 0 0 Jim Bob 1994 9001
当我可以手动很好地预加载模型时,为什么通过db.First(…)获取模型不会自动预加载?
首先,我建议阅读文档。 这里有点解释。看来您使用旧版本的可能性更大。更新的文档说明了如何使用此标记gorm:"PRELOAD",默认情况下将其设置为true。因此,如果您想禁用字段使用gorm:"PRELOAD:false"。
gorm:"PRELOAD"
gorm:"PRELOAD:false"
之后,必须使用db.Set("gorm:auto_preload", true)才能正确获取它。如果要通过应用程序使用预加载,则可以重新分配db以具有auto_preload功能:
db.Set("gorm:auto_preload", true)
db = db.Set("gorm:auto_preload", true)
例:
package main import "github.com/jinzhu/gorm" import _ "github.com/jinzhu/gorm/dialects/sqlite" type User struct { gorm.Model Name string Car Car Account Account `gorm:"PRELOAD:false"` } type Car struct { gorm.Model Type int UserID uint } type Account struct { gorm.Model Powerlevel int UserID uint } func main() { db, err := gorm.Open("sqlite3", "./data.db") db.LogMode(true) if err != nil { println(err.Error()) } //Migrate the tables db.AutoMigrate(&User{}) db.AutoMigrate(&Car{}) db.AutoMigrate(&Account{}) // Initialize our models var testUser User var car = Car{Type: 1994} var account = Account{Powerlevel: 9001} testUser.Name = "Jim Bob" testUser.Car = car testUser.Account = account // Save the user db.Create(&testUser) // Get a new user var newUser User // override db instance to always prefetch //db = db.Set("gorm:auto_preload", true) db.Set("gorm:auto_preload", true).First(&newUser) println(newUser.Name) println(newUser.Car.Type) println(newUser.Account.Powerlevel) // Explicitly preload // No need to use two seperate statements, you can just chain them :) db.Preload("Car").Preload("Account").First(&newUser) //db.Preload("Account").First(&newUser) println(newUser.Name) println(newUser.Car.Type) println(newUser.Account.Powerlevel) }
输出:
(/home/william/main.go:46) [2018-06-15 08:56:53] [0.34ms] INSERT INTO "users" ("created_at","updated_at","deleted_at","name") VALUES ('2018-06-15 08:56:53','2018-06-15 08:56:53',NULL,'Jim Bob') [1 rows affected or returned ] (/home/william/main.go:46) [2018-06-15 08:56:53] [0.11ms] INSERT INTO "cars" ("created_at","updated_at","deleted_at","type","user_id") VALUES ('2018-06-15 08:56:53','2018-06-15 08:56:53',NULL,'1994','9') [1 rows affected or returned ] (/home/william/main.go:46) [2018-06-15 08:56:53] [0.10ms] INSERT INTO "accounts" ("created_at","updated_at","deleted_at","powerlevel","user_id") VALUES ('2018-06-15 08:56:53','2018-06-15 08:56:53',NULL,'9001','9') [1 rows affected or returned ] (/home/william/main.go:51) [2018-06-15 08:56:53] [0.69ms] SELECT * FROM "users" WHERE "users"."deleted_at" IS NULL ORDER BY "users"."id" ASC LIMIT 1 [1 rows affected or returned ] (/home/william/main.go:51) [2018-06-15 08:56:53] [1.93ms] SELECT * FROM "cars" WHERE "cars"."deleted_at" IS NULL AND (("user_id" IN ('1'))) ORDER BY "cars"."id" ASC [1 rows affected or returned ] Jim Bob 1994 <-- notice here preload is on 0 <-- notice here preload was turned off Account Type (/home/william/main.go:59) [2018-06-15 08:56:53] [0.28ms] SELECT * FROM "users" WHERE "users"."deleted_at" IS NULL AND "users"."id" = '1' ORDER BY "users"."id" ASC LIMIT 1 [1 rows affected or returned ] (/home/william/main.go:59) [2018-06-15 08:56:53] [0.33ms] SELECT * FROM "cars" WHERE "cars"."deleted_at" IS NULL AND (("user_id" IN ('1'))) ORDER BY "cars"."id" ASC [1 rows affected or returned ] (/home/william/main.go:60) [2018-06-15 08:56:53] [0.27ms] SELECT * FROM "users" WHERE "users"."deleted_at" IS NULL AND "users"."id" = '1' ORDER BY "users"."id" ASC LIMIT 1 [1 rows affected or returned ] (/home/william/main.go:60) [2018-06-15 08:56:53] [0.46ms] SELECT * FROM "accounts" WHERE "accounts"."deleted_at" IS NULL AND (("user_id" IN ('1'))) ORDER BY "accounts"."id" ASC [1 rows affected or returned ] (/home/william/main.go:60) [2018-06-15 08:56:53] [0.40ms] SELECT * FROM "cars" WHERE "cars"."deleted_at" IS NULL AND (("user_id" IN ('1'))) ORDER BY "cars"."id" ASC [1 rows affected or returned ] Jim Bob 1994 9001