gorm中的關聯操作詳解

一對一belong to屬于:可以理解為舔狗認為自己屬于女神,而女神都不知道舔狗的存在type Girl struct {IdintName string}type Dog struct {IdintNamestringGirlId intGirlGirl}遷移 schemadb.AutoMigrate(&Dog{})//此時會將Girl和Dog都生成
hasone擁有:可以理解為女神知道舔狗的存在,舔狗只需要留一根“狗鏈子”在女神創建的時候交給女神就好了type Dog struct {IdintNamestringGirlId int } type Girl struct {IdintName stringDogDog } //db.AutoMigrate(&Girl{})//只有一個Girl表生成 db.AutoMigrate(&Girl{}, &Dog{}) d := Dog{Id: 1,Name: "haha0"} db.Create(&Girl{Id: 1,Name: "nv0",Dog:d}) //此時Dog中的GirlId字段被自動填寫
查詢var girl Girl db.First(&girl, 1) fmt.Println(girl)直接這樣查是不行的,這是需要先預加載改成:db.Preload("Dog").First(&girl, 1)
關系操作//給舔狗創建關系db.Model(&Girl{Id:1}).Association("Dog").Append(&dog)上面是hasone的情況,belong to 的情況正好相反Append換為Delete,是刪除連接換為Replace(&g1,&g2),是替換連接Clear(),自身去掉所有關系
一對多還是上面的例子只需要微微改動` type Dog struct {IdintNamestringGirlId int//GirlGirl}
type Girl struct { Idint Name string Dogs []Dog}d0 := Dog{Id: 1, Name: "haha0"}d1 := Dog{Id: 2, Name: "haha2"}g := &Girl{Id: 1, Name: "nv0", Dogs: []Dog{d0, d1},}db.Create(&g)db.AutoMigrate(&Girl{}, &Dog{})`查詢:db.Preload("Dogs").First(&girl)還是預加載,需要如果條件判斷

  • 類似內聯`// 帶條件的預加載 Orderdb.Preload("Orders", "state NOT IN (?)", "cancelled").Find(&users)// SELECT * FROM users;// SELECT * FROM orders WHERE user_id IN (1,2,3,4) AND state NOT IN ('cancelled');
db.Where("state = ?", "active").Preload("Orders", "state NOT IN (?)", "cancelled").Find(&users)// SELECT * FROM users WHERE state = 'active';// SELECT * FROM orders WHERE user_id IN (1,2) AND state NOT IN ('cancelled');
`
  • 自定義預加載db.Preload("Orders", func(db *gorm.DB) *gorm.DB { return db.Order("orders.amount DESC") }).Find(&users) // SELECT * FROM users; // SELECT * FROM orders WHERE user_id IN (1,2,3,4) order by orders.amount DESC;
  • 鏈式預加載修改結構體 type Info struct {Idintmoney intGogId int } type Dog struct {IdintNamestringGirlId int//GirlGirlInfo Info }注意生成數據庫表的時候,各個表生成的順序,否則報錯db.AutoMigrate(&Girl{}, &Dog{}, &Info{})在查詢db.Preload("Dogs.Info").Preload("Dogs").First(&girl)同時加條件的話和上面也一樣,但是需要注意查詢條件只適用于她所在的預加載的那一層例如:db.Preload("Dogs.Info", "money>100").Preload("Dogs").First(&girl)輸出結果小于100的info信息會沒有,但是dog依然會查出來,money>100條件影響不到Preload("Dogs")那怎么樣可以實現輸出結果小于100的info信息會沒有 , dog也沒有呢,可以使用join
join注意 Join適用于一對一的關系,例如: has one, belongs to上面的問題可以:db.Preload("Dogs", func(db *gorm.DB) *gorm.DB {return db.Joins("Info").Where("money>200")}).First(&girl)
多對多創建格式:type Info struct {IdintMoney intDogId int } type Girl struct {IdintName stringDogs []Doggorm:"many2many:girl_dog"} type Dog struct {IdintNamestringGirl[]Girlgorm:"many2many:girl_dog" InfoInfo }
查詢1.只想查舔狗的女神有哪些,不要舔狗信息
gorm中的關聯操作詳解

文章插圖
2.舔狗信息也要,就加上預加載
gorm中的關聯操作詳解

文章插圖
想加條件和一對多差不多
關系維護還是那幾個函數
gorm中的關聯操作詳解

文章插圖
刪除最好用事務
最后
gorm中的關聯操作詳解

文章插圖
注意多對多情況的FK和refer和一對一/多正好相反了
博客是觀看b站up主(go圈里最會寫js的奇淼)筆記鏈接:https://www.bilibili.com/video/BV1E64y1472a?p=10&spm_id_from=pageDriver&vd_source=7de631e1910751f66cb6a72edf044dab
【gorm中的關聯操作詳解】

    推薦閱讀