中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

手機做推廣比較好的網(wǎng)站關(guān)鍵詞排名怎么做上首頁

手機做推廣比較好的網(wǎng)站,關(guān)鍵詞排名怎么做上首頁,網(wǎng)站后臺導(dǎo)航隨意添加,wordpress 主菜單 背景gorm day8 gorm Has Many關(guān)系gorm Many To Many關(guān)系 gorm Has Many關(guān)系 Has Many 在GORM(Go的一個對象關(guān)系映射庫)中,“Has Many” 關(guān)系表示一個實體與另一個實體之間的一對多關(guān)系。這意味著一個實體(我們稱之為"父"…

gorm day8

  • gorm Has Many關(guān)系
  • gorm Many To Many關(guān)系

gorm Has Many關(guān)系

Has Many

在GORM(Go的一個對象關(guān)系映射庫)中,“Has Many” 關(guān)系表示一個實體與另一個實體之間的一對多關(guān)系。這意味著一個實體(我們稱之為"父"實體)可以擁有指向多個其他實體("子"實體)的引用。這種關(guān)系在數(shù)據(jù)庫中通常通過使用外鍵在"子"實體上來實現(xiàn)。

舉個例子來說明GORM中定義和使用的Has Many關(guān)系:
示例:用戶和訂單
假設(shè)我們有兩個模型:User 和 Order。一個用戶可以擁有多個訂單,但每個訂單只能屬于一個用戶。這是一個典型的"Has Many"關(guān)系。

package mainimport ("gorm.io/driver/sqlite""gorm.io/gorm"
)type User struct {gorm.ModelName   stringOrders []Order // Has Many 關(guān)系
}type Order struct {gorm.ModelProductName stringUserID      uint // 外鍵
}func main() {db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})if err != nil {panic("failed to connect database")}// 自動遷移模式db.AutoMigrate(&User{}, &Order{})// 創(chuàng)建用戶和訂單user := User{Name: "John Doe", Orders: []Order{{ProductName: "Book"},{ProductName: "Pen"},}}db.Create(&user) // GORM 會自動處理外鍵關(guān)系
}

定義模型:我們定義了兩個結(jié)構(gòu)體 User 和 Order 來作為我們的模型。User 結(jié)構(gòu)體中包含一個 Orders 字段,它是一個 Order 結(jié)構(gòu)體切片,表示一個用戶可以有多個訂單。
外鍵:在 Order 結(jié)構(gòu)體中,UserID 字段作為外鍵,用來存儲創(chuàng)建該訂單的用戶的ID。這個字段告訴GORM這兩個模型之間的關(guān)聯(lián)方式。
自動遷移:db.AutoMigrate(&User{}, &Order{}) 告訴GORM自動創(chuàng)建或修改數(shù)據(jù)庫表以匹配模型的結(jié)構(gòu)。這包括設(shè)置正確的外鍵關(guān)系。
創(chuàng)建記錄:當我們創(chuàng)建一個 User 實例并設(shè)置其 Orders 字段時,GORM知道如何將訂單記錄插入 orders 表,并設(shè)置每個訂單的 UserID 字段,以反映它們屬于該用戶。

文檔例子
has many與另一個模型建立了一對多的連接。不同于has one,擁有者可以有零或多個關(guān)聯(lián)模型。
例如,您的應(yīng)用包含user和credit card模型,且每個user可以有多張credit card。

// User 有多張 CreditCard,UserID 是外鍵
type User struct {gorm.ModelCreditCards []CreditCard
}type CreditCard struct {gorm.ModelNumber stringUserID uint
}

這個看起來就還是很直觀的。之間的關(guān)系還是很清楚的。
User結(jié)構(gòu)體:代表應(yīng)用中的用戶。它繼承了gorm.Model,這是GORM提供的基礎(chǔ)模型,包含了一些常用字段,如ID, CreatedAt, UpdatedAt, DeletedAt。User結(jié)構(gòu)體中包含一個CreditCards字段,這是一個CreditCard結(jié)構(gòu)體的切片。這表明一個用戶可以關(guān)聯(lián)多張信用卡。GORM通過這個字段理解到User和CreditCard之間存在一對多關(guān)系。

CreditCard結(jié)構(gòu)體:代表信用卡。同樣繼承了gorm.Model,并且有一個Number字段存儲信用卡號,以及一個UserID字段。UserID是一個無符號整型,用于存儲這張信用卡所屬用戶的ID。這個字段是實現(xiàn)一對多關(guān)系的外鍵,它指向User表的主鍵ID。

關(guān)系和外鍵
在這個關(guān)系中,UserID字段在CreditCard結(jié)構(gòu)體內(nèi)充當外鍵,指向User表的ID字段。這表示每張CreditCard都屬于一個特定的User。

當使用GORM進行數(shù)據(jù)庫操作(如創(chuàng)建、查詢)時,GORM會自動處理這些關(guān)聯(lián)關(guān)系。例如,當你為一個User添加多張CreditCard并保存到數(shù)據(jù)庫時,GORM會自動填充每張CreditCard的UserID字段,確保關(guān)系的正確性。

重寫外鍵

要定義has many關(guān)系,通用必須存在外鍵。默認的外鍵名是擁有者的類型名加上其主鍵字段名。
例如,要定義一個屬于User的模型,則其外鍵應(yīng)該是UserID。
此外,想要使用另一個字段作為外鍵,你可以使用foreignKey標簽自定義它:

type User struct {gorm.ModelCreditCards []CreditCard `gorm:"foreignKey:UserRefer"`
}type CreditCard struct {gorm.ModelNumber    stringUserRefer uint
}

解讀:
在GORM中定義"Has Many"關(guān)系時,確實需要有一個外鍵存在于"子"模型中,用以指向"父"模型的主鍵,從而表明兩者之間的關(guān)聯(lián)。這段內(nèi)容詳細解釋了如何在GORM中設(shè)置和自定義這種一對多(“Has Many”)關(guān)系,以及如何指定外鍵。

默認外鍵命名規(guī)則
GORM的默認行為是根據(jù)"父"模型的類型名和其主鍵字段名來自動生成外鍵名。例如,如果有一個模型叫User(父模型),其主鍵字段名默認是ID(因為gorm.Model包含一個名為ID的字段作為主鍵),那么屬于User的任何模型(子模型)的默認外鍵名將會是UserID。

自定義外鍵
管GORM提供了一個默認的外鍵命名規(guī)則,但在某些情況下,默認規(guī)則可能不適合你的數(shù)據(jù)庫設(shè)計。可能你想要的外鍵名與默認提供的不同,或者你的數(shù)據(jù)庫已經(jīng)有了既定的外鍵命名規(guī)范。為了滿足這種需求,GORM允許通過foreignKey標簽來自定義外鍵字段。

示例解讀
在給定的示例中,User模型和CreditCard模型之間存在一個"Has Many"關(guān)系,即一個用戶可以擁有多張信用卡。示例通過在User結(jié)構(gòu)體中的CreditCards字段旁使用gorm:"foreignKey:UserRefer"標簽明確指定了CreditCard模型使用UserRefer字段作為外鍵,而不是默認的UserID。

這意味著:
User模型通過CreditCards字段關(guān)聯(lián)多張CreditCard。
在CreditCard模型中,UserRefer字段被用作外鍵,指向User模型的主鍵ID字段。這個"指向"的意思是,子表中的外鍵字段的值對應(yīng)于父表中某條記錄的主鍵值。
這種關(guān)系允許GORM在操作數(shù)據(jù)庫時自動處理這些關(guān)聯(lián),比如在查詢用戶時同時獲取其所有信用卡信息。

重寫引用

GORM 通常使用使用者的主鍵作為外鍵的值。對于上面的例子,它是User的ID字段。
為user添加credit card時,GORM會將user的ID字段保存到credit card的UserID字段。
同樣的,您也可以使用標簽references來更改它,例如:

type User struct {gorm.ModelMemberNumber stringCreditCards  []CreditCard `gorm:"foreignKey:UserNumber;references:MemberNumber"`
}type CreditCard struct {gorm.ModelNumber     stringUserNumber string
}

這里我主要說說references
references:MemberNumber是GORM中用于自定義外鍵關(guān)聯(lián)的一個標簽,它指定了在建立模型間關(guān)系時,應(yīng)該引用的字段。 當你在GORM中定義模型關(guān)系時,foreignKey和references標簽通常一起使用來指明這種自定義關(guān)系。 讓我來具體解釋一下references:MemberNumber的作用和意義。

默認外鍵引用
在沒有明確指定references標簽的情況下,GORM默認使用"父"模型的主鍵字段(通常是ID字段)作為外鍵關(guān)聯(lián)的引用。這意味著,在一對多(Has Many)或一對一(Has One)關(guān)系中,"子"模型中的外鍵字段將會存儲與"父"模型的ID字段相對應(yīng)的值。

自定義外鍵引用
使用references標簽,你可以指定一個不同于"父"模型的ID字段的其他字段作為外鍵引用。這在你想要建立模型間關(guān)系,但又不想使用默認的ID字段作為關(guān)聯(lián)依據(jù)時非常有用。

例子解讀:
references:MemberNumber告訴GORM,當建立User和CreditCard之間的關(guān)系時,不是使用User模型的ID字段,而是使用User模型中的MemberNumber字段作為引用。這意味著:
CreditCard模型中的
UserNumber字段將會存儲對應(yīng)User模型中MemberNumber字段的值。

這樣的設(shè)計使得CreditCard與User之間的關(guān)聯(lián)不再依賴于用戶的ID,而是依賴于用戶的MemberNumber,這可能是一個業(yè)務(wù)邏輯上的需求,例如當MemberNumber是用戶在系統(tǒng)中的一個業(yè)務(wù)標識符時。

作用和好處
這種自定義關(guān)系的好處是提供了更大的靈活性,允許開發(fā)者根據(jù)實際的業(yè)務(wù)需求和數(shù)據(jù)模型設(shè)計來建立模型間的關(guān)系。它特別有用于那些需要根據(jù)非主鍵字段建立關(guān)系的場景,從而可以更準確地反映實際的業(yè)務(wù)邏輯和數(shù)據(jù)關(guān)系。

多態(tài)關(guān)聯(lián)

GORM為has one和has many提供了多態(tài)關(guān)聯(lián)支持,他會將擁有者實體的表名、主鍵都保存到多態(tài)類型的字段中。

type Dog struct {ID   intName stringToys []Toy `gorm:"polymorphic:Owner;"`
}type Toy struct {ID        intName      stringOwnerID   intOwnerType string
}db.Create(&Dog{Name: "dog1", Toys: []Toy{{Name: "toy1"}, {Name: "toy2"}}})
// INSERT INTO `dogs` (`name`) VALUES ("dog1")
// INSERT INTO `toys` (`name`,`owner_id`,`owner_type`) VALUES ("toy1","1","dogs"), ("toy2","1","dogs")

解讀:
這段內(nèi)容介紹了GORM如何實現(xiàn)和支持多態(tài)關(guān)聯(lián)(Polymorphic Associations)對于"Has One"和"Has Many"關(guān)系。多態(tài)關(guān)聯(lián)是一種數(shù)據(jù)庫設(shè)計模式允許一個模型(在這個例子中是Toy)關(guān)聯(lián)到多個模型(如Dog、Cat等),而不是只能關(guān)聯(lián)到一個固定的模型。這種設(shè)計增加了數(shù)據(jù)庫模型的靈活性和復(fù)用性。

示例解析:
在給定的例子中,Dog和Toy模型通過多態(tài)關(guān)系進行關(guān)聯(lián)。這種關(guān)系允許Toy不僅僅屬于Dog,也可以屬于其他類型的實體,如Cat等,只要它們采用相同的多態(tài)設(shè)計模式。

Dog模型
Dog模型簡單明了,包含ID和Name字段。此外,它包含一個Toys字段,這是一個Toy切片,表示每只狗可以擁有多個玩具。通過gorm:"polymorphic:Owner;"標簽,GORM知道這是一個多態(tài)關(guān)聯(lián)。

Toy模型
Toy模型包含ID、Name、OwnerID和OwnerType字段。OwnerID和OwnerType是實現(xiàn)多態(tài)關(guān)聯(lián)的關(guān)鍵:
OwnerID存儲擁有者的主鍵值。
OwnerType存儲擁有者的類型,通常是擁有者實體的表名。

數(shù)據(jù)庫操作示例
創(chuàng)建一個Dog實例并為其分配玩具時,如db.Create(&Dog{Name: “dog1”, Toys: []Toy{{Name: “toy1”}, {Name: “toy2”}}}),GORM會先在dogs表中插入一條記錄,然后在toys表中插入兩條記錄。
在toys表中,每個玩具的owner_id會被設(shè)置為對應(yīng)Dog實例的ID,而owner_type會被設(shè)置為dogs。這樣就實現(xiàn)了多態(tài)關(guān)聯(lián):Toy知道它屬于哪個表的哪條記錄。

作用和好處
多態(tài)關(guān)聯(lián)的主要好處是提供了極高的靈活性。 在沒有多態(tài)關(guān)聯(lián)的情況下,如果你想讓Toy既可以屬于Dog也可以屬于Cat,你可能需要為每種關(guān)系創(chuàng)建不同的字段(比如dog_id和cat_id),或者創(chuàng)建不同的關(guān)聯(lián)表。多態(tài)關(guān)聯(lián)避免了這種冗余,允許Toy通過OwnerID和OwnerType字段靈活地關(guān)聯(lián)到任意類型的實體。

總結(jié):
這種設(shè)計模式在實際應(yīng)用中非常有用,尤其是在存在多種類型的實體,并且這些實體都可能與某個資源有關(guān)聯(lián)時。通過多態(tài)關(guān)聯(lián),可以簡化模型設(shè)計,減少數(shù)據(jù)庫復(fù)雜性,同時保持了數(shù)據(jù)結(jié)構(gòu)的靈活性和擴展性。

你可以使用標簽polymorphicValue來更改多態(tài)類型的值,例如:

type Dog struct {ID   intName stringToys []Toy `gorm:"polymorphic:Owner;polymorphicValue:master"`
}type Toy struct {ID        intName      stringOwnerID   intOwnerType string
}db.Create(&Dog{Name: "dog1", Toys: []Toy{{Name: "toy1"}, {Name: "toy2"}}})
// INSERT INTO `dogs` (`name`) VALUES ("dog1")
// INSERT INTO `toys` (`name`,`owner_id`,`owner_type`) VALUES ("toy1","1","master"), ("toy2","1","master")

解讀:
這段內(nèi)容介紹了如何在使用GORM進行多態(tài)關(guān)聯(lián)時,通過polymorphicValue標簽自定義多態(tài)類型的值。在多態(tài)關(guān)聯(lián)中,通常需要兩個字段來確定關(guān)聯(lián)的目標:一個是指向目標實體主鍵的外鍵(如OwnerID),另一個是表示目標實體類型的字段(如OwnerType)。通過polymorphicValue標簽,我們可以明確指定在創(chuàng)建關(guān)聯(lián)時,OwnerType字段應(yīng)該保存的具體值,而不是使用默認的表名。

總結(jié):使用polymorphicValue標簽允許開發(fā)者在設(shè)計數(shù)據(jù)庫模型時擁有更高的靈活性和控制權(quán)。它使得開發(fā)者可以根據(jù)業(yè)務(wù)邏輯需要,自定義多態(tài)關(guān)聯(lián)中OwnerType字段的值,而不是簡單地使用表名。

預(yù)加載

GORM 可以通過Preload預(yù)加載has many關(guān)聯(lián)的記錄。

自引用Has Many

type User struct {gorm.ModelName      stringManagerID *uintTeam      []User `gorm:"foreignkey:ManagerID"`
}

解讀:

這段內(nèi)容展示了如何在使用GORM(一個Go語言的ORM庫)定義自引用的"Has Many"關(guān)系。在這個例子中,User模型通過自引用來表示一個組織結(jié)構(gòu),其中一個用戶可以是另一個用戶的經(jīng)理(或上級),并且一個經(jīng)理可以管理多個下屬。這種關(guān)系在數(shù)據(jù)庫中通常用于表示層級或樹狀結(jié)構(gòu),如員工和他們的管理者。

結(jié)構(gòu)體定義
ManagerID: 指向另一個User實例的指針,代表這個用戶的經(jīng)理。這是一個可空字段(因為它是一個指針),允許某些用戶沒有經(jīng)理(例如,最高級別的經(jīng)理)。
Team: 一個User切片,通過gorm:"foreignkey:ManagerID"標簽指明,這個切片表示所有將當前用戶實例作為經(jīng)理的用戶集合。這里使用的foreignkey:ManagerID標簽告訴GORM,Team字段中的用戶是通過ManagerID字段與當前用戶關(guān)聯(lián)的。

自引用的"Has Many"關(guān)系
在這個模型中,ManagerID字段用于標識每個用戶的直接上級(經(jīng)理),而Team字段則用于收集所有直接下屬。通過這種方式,你可以構(gòu)建一個組織中所有員工的層級關(guān)系。例如,如果一個用戶(A)的ManagerID指向另一個用戶(B),那么用戶B的Team切片將包含用戶A,表示用戶A是用戶B的下屬。

實現(xiàn)細節(jié)
自引用:這個模型利用了自引用,即User結(jié)構(gòu)體中包含了指向相同類型(User)的字段。這在Go中是允許的,并且在ORM中用于表示復(fù)雜的關(guān)系,如樹形結(jié)構(gòu)或圖結(jié)構(gòu)。

外鍵關(guān)聯(lián):通過gorm:"foreignkey:ManagerID"標簽,GORM知道如何將User表中的記錄通過ManagerID連接起來,建立一種層級關(guān)系。這允許GORM在執(zhí)行查詢時,能夠自動解析這些關(guān)系,例如在查詢一個用戶時,同時獲取他的直接下屬列表。

外鍵約束

你可以通過constraint:OnUpdate、OnDelete實現(xiàn)外鍵約束,在使用GORM進行遷移時它會被字段創(chuàng)建。例如:

type User struct {gorm.ModelCreditCards []CreditCard `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`
}type CreditCard struct {gorm.ModelNumber stringUserID uint
}

你也可以在刪除記錄時通過Select來刪除has many關(guān)聯(lián)的記錄。


gorm Many To Many關(guān)系

Many To Many

在GORM中,"Many To Many"關(guān)系是指兩個模型之間存在的關(guān)聯(lián),其中一個實例可以關(guān)聯(lián)到多個實例,反之亦然。這種關(guān)系通常通過一個關(guān)聯(lián)表(或稱為連接表)來實現(xiàn),該表存儲兩個模型之間關(guān)聯(lián)的外鍵。

示例:用戶和角色
假設(shè)我們有兩個模型:User和Role。一個用戶可以有多個角色,同時一個角色也可以被多個用戶共享。這是一個典型的"Many To Many"關(guān)系。

定義模型
首先,我們定義User和Role模型,并使用GORM的標簽來描述它們之間的"Many To Many"關(guān)系。

package mainimport ("gorm.io/driver/sqlite""gorm.io/gorm"
)type User struct {gorm.ModelName  stringRoles []Role `gorm:"many2many:user_roles;"`
}type Role struct {gorm.ModelName  stringUsers []User `gorm:"many2many:user_roles;"`
}

在這個例子中,User和Role模型通過Roles和Users字段相互關(guān)聯(lián),而gorm:"many2many:user_roles;"標簽指定了用于存儲這種多對多關(guān)系的關(guān)聯(lián)表名稱為user_roles。

自動遷移
GORM提供自動遷移功能,可以根據(jù)模型定義自動創(chuàng)建或更新數(shù)據(jù)庫表結(jié)構(gòu)。

func main() {db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})if err != nil {panic("failed to connect database")}// 自動遷移db.AutoMigrate(&User{}, &Role{})
}

創(chuàng)建關(guān)聯(lián)
接下來,我們可以創(chuàng)建一些User和Role實例,并設(shè)置它們之間的關(guān)聯(lián)。

func main() {// ...數(shù)據(jù)庫連接和自動遷移代碼// 創(chuàng)建角色adminRole := Role{Name: "Admin"}userRole := Role{Name: "User"}db.Create(&adminRole)db.Create(&userRole)// 創(chuàng)建用戶并分配角色user := User{Name: "John", Roles: []Role{adminRole, userRole}}db.Create(&user)
}

在上面的代碼中,我們首先創(chuàng)建了兩個Role實例:Admin和User。然后,我們創(chuàng)建了一個User實例John,并通過Roles字段將John與這兩個角色關(guān)聯(lián)起來。當我們執(zhí)行db.Create(&user)時,GORM會自動處理這些關(guān)聯(lián),不僅在users和roles表中插入相應(yīng)的記錄,還會在user_roles關(guān)聯(lián)表中插入表示這些關(guān)聯(lián)的記錄。

小結(jié)
通過GORM,我們可以相對簡單地實現(xiàn)和管理"Many To Many"關(guān)系。GORM自動處理關(guān)聯(lián)表的創(chuàng)建和更新,開發(fā)者只需專注于模型的定義和業(yè)務(wù)邏輯。這種抽象使得處理復(fù)雜的數(shù)據(jù)庫關(guān)聯(lián)變得更加直觀和高效。

gorm文檔解讀

Many to Many會在兩個model中添加一張連接表
例如,你的英語包含了user和language,且一個user可以說多種language,多個user也可以說一種language。

// User 擁有并屬于多種 language,`user_languages` 是連接表
type User struct {gorm.ModelLanguages []Language `gorm:"many2many:user_languages;"`
}type Language struct {gorm.ModelName string
}

當使用GORM的AutoMigrate為User創(chuàng)建表時,GORM會自動創(chuàng)建連接表。

反向引用

// User 擁有并屬于多種 language,`user_languages` 是連接表
type User struct {gorm.ModelLanguages []*Language `gorm:"many2many:user_languages;"`
}type Language struct {gorm.ModelName stringUsers []*User `gorm:"many2many:user_languages;"`
}

解讀:
這段內(nèi)容展示了如何在GORM中實現(xiàn)和使用**"Many To Many"關(guān)系的反向引用。**在這個示例中,有兩個模型:User和Language。一個用戶可以會說多種語言,同時一種語言也可以被多個用戶所會說。這種關(guān)系通過一個名為user_languages的連接表來表示和存儲。連接表是在數(shù)據(jù)庫中用來存儲兩個表之間"多對多"關(guān)系的第三個表,它通常包含指向兩個表主鍵的外鍵。

User模型
User模型包含一個Languages字段,這是一個指向Language結(jié)構(gòu)的指針切片。這表明一個User可以關(guān)聯(lián)多個Language。
gorm:"many2many:user_languages;"標簽指定了用來存儲User和Language之間關(guān)系的連接表名稱為user_languages。這個標簽告訴GORM如何管理這兩個模型之間的多對多關(guān)系。

Language模型
Language模型類似地定義了一個Users字段,這是一個指向User結(jié)構(gòu)的指針切片。這表示一個Language可以被多個User所使用。
它同樣使用了gorm:"many2many:user_languages;"標簽來指定連接表。這樣,GORM就知道如何通過user_languages表反向管理Language到User的多對多關(guān)系。

連接表(user_languages)
連接表user_languages在數(shù)據(jù)庫中通常會有兩個主要的列:一個是user_id列,用來存儲User表中某個用戶的ID;另一個是language_id列,用來存儲Language表中某種語言的ID。每一行代表一個用戶與一種語言之間的關(guān)系。

反向引用的作用
雙向查詢這種反向引用的設(shè)置允許你從兩個方向查詢關(guān)系。即你可以輕松地找到一個用戶會說的所有語言,也可以找到說某種語言的所有用戶。
數(shù)據(jù)完整性:通過管理user_languages連接表,GORM能夠確保在添加、更新或刪除用戶和語言時,保持數(shù)據(jù)的一致性和完整性。
靈活性:這種模型設(shè)計提供了很高的靈活性,適用于需要雙向多對多關(guān)系的場景,比如用戶和群組、商品和分類等。

總結(jié),通過使用GORM的many2many標簽和指定連接表,你可以方便地在兩個模型之間建立和管理復(fù)雜的多對多關(guān)系,同時保持代碼的清晰和數(shù)據(jù)庫的整潔。

重寫外鍵

對于many2many關(guān)系,連接表會同時擁有兩個模型的外鍵,例如:

type User struct {gorm.ModelLanguages []Language `gorm:"many2many:user_languages;"`
}type Language struct {gorm.ModelName string
}// 連接表:user_languages
//   foreign key: user_id, reference: users.id
//   foreign key: language_id, reference: languages.id

若要重寫它們,可以使用標簽foreignKey,references、joinforeignKey、joinReferences。當然您不需要使用全部的標簽,你可以僅使用其中的一個重寫部分的外鍵、引用。

type User struct {gorm.ModelProfiles []Profile `gorm:"many2many:user_profiles;foreignKey:Refer;joinForeignKey:UserReferID;References:UserRefer;joinReferences:ProfileRefer"`Refer    uint      `gorm:"index:,unique"`
}type Profile struct {gorm.ModelName      stringUserRefer uint `gorm:"index:,unique"`
}// 會創(chuàng)建連接表:user_profiles
//   foreign key: user_refer_id, reference: users.refer
//   foreign key: profile_refer, reference: profiles.user_refer

注意:某些數(shù)據(jù)庫只允許在唯一索引字段上創(chuàng)建外鍵,如果你在遷移時會創(chuàng)建外鍵,則需要指定unique index標簽

解讀:
在GORM中,通過使用many2many標簽,你可以定義兩個模型之間的多對多關(guān)系,并且默認情況下,GORM會自動創(chuàng)建一個連接表來管理這種關(guān)系。連接表包含兩個外鍵,分別指向參與關(guān)系的兩個模型的主鍵。然而,有時候默認的外鍵和引用規(guī)則可能不符合你的數(shù)據(jù)庫設(shè)計需求,這時候你可以使用foreignKey、references、joinForeignKey、和joinReferences標簽來重寫這些規(guī)則。

標簽解釋
foreignKey: 指定本模型在連接表中使用的外鍵字段。
references: 指定foreignKey指向本模型中的哪個字段。
joinForeignKey: 指定另一模型在連接表中使用的外鍵字段。
joinReferences: 指定joinForeignKey指向另一模型中的哪個字段。

示例解讀
在提供的示例中,User和Profile模型通過一個名為user_profiles的連接表建立多對多關(guān)系。與前面的User和Language模型的默認外鍵規(guī)則不同,這里通過標簽明確指定了連接表中使用的外鍵名稱和它們所引用的字段。

User模型
foreignKey:Refer:指定User模型在user_profiles連接表中使用的外鍵字段應(yīng)該基于User模型的Refer字段。
joinForeignKey:UserReferID:指定連接表中代表User模型的外鍵字段名稱為UserReferID。
References:UserRefer:這似乎是一個筆誤或誤解?;谏舷挛?#xff0c;它應(yīng)該是用來指定foreignKey引用User模型中的哪個字段,但Refer已被作為foreignKey,所以這里可能是要表達foreignKey對應(yīng)的實際字段是Refer。

Profile模型
joinReferences:ProfileRefer:指定joinForeignKey在Profile模型中引用的字段。但示例中沒有直接展示joinForeignKey的定義,從上下文推測,joinForeignKey可能是通過gorm:"many2many:user_profiles;"在User模型中定義的joinForeignKey:UserReferID對應(yīng)的另一邊,意味著ProfileRefer應(yīng)該是user_profiles表中的列名,指向Profile模型。

連接表user_profiles
foreign key: user_refer_id, reference: users.refer:表示user_profiles表中的user_refer_id列是外鍵,它引用users表中的refer列。
foreign key: profile_refer, reference: profiles.user_refer:表示user_profiles表中的profile_refer列是外鍵,它引用profiles表中的user_refer列。

注意事項
唯一索引(Unique Index):某些數(shù)據(jù)庫要求只能在具有唯一索引的字段上創(chuàng)建外鍵。這就意味著,如果你打算在遷移時創(chuàng)建外鍵,那么被引用的字段(如Refer和UserRefer)需要被標記為唯一索引,這在GORM中可以通過gorm:"index:,unique"標簽來實現(xiàn)。

自引用 Many2Many

type User struct {gorm.ModelFriends []*User `gorm:"many2many:user_friends"`
}// 會創(chuàng)建連接表:user_friends
//   foreign key: user_id, reference: users.id
//   foreign key: friend_id, reference: users.id

解讀:
這段內(nèi)容說明了如何在使用GORM時定義一個自引用的"Many To Many"關(guān)系,具體示例為用戶與其朋友之間的關(guān)系。在這個例子中,User模型通過一個名為user_friends的連接表來實現(xiàn)用戶之間的多對多朋友關(guān)系。這意味著每個用戶可以有多個朋友,而每個朋友也可以同時被多個用戶標記為朋友。

User模型
User模型包含了一個Friends字段,這是一個指向User類型的切片。這個字段使用gorm:"many2many:user_friends"標簽來聲明一個多對多關(guān)系,并指定user_friends作為連接表。

連接表user_friends
連接表user_friends用于存儲用戶之間朋友關(guān)系的信息。它包含兩個外鍵字段:user_id和friend_id。
user_id:作為外鍵,指向users表的id字段,表示在這個朋友關(guān)系中的一個用戶。
friend_id:同樣作為外鍵,也指向users表的id字段,但表示在這個關(guān)系中的另一個用戶,即朋友。
這個設(shè)計允許每條記錄在user_friends表中唯一地標識一對朋友關(guān)系,其中user_id和friend_id分別代表這對關(guān)系中的兩個用戶。值得注意的是,由于這是自引用關(guān)系,user_id和friend_id都引用同一個表(users表)的id字段。

自引用的"Many To Many"關(guān)系的特點
對稱性:在現(xiàn)實世界中,如果用戶A是用戶B的朋友,那么用戶B通常也是用戶A的朋友。然而,在數(shù)據(jù)庫層面,這種對稱性需要通過在user_friends表中為每對朋友關(guān)系添加兩條記錄來手動維護,除非應(yīng)用邏輯層提供了處理這一點的機制。
靈活性:這種模型設(shè)計極大地增加了數(shù)據(jù)庫模型的靈活性,允許用戶動態(tài)地添加或刪除朋友關(guān)系。
查詢:查詢一個用戶的所有朋友涉及到連接表的自連接查詢,這可能比直接的"一對多"或"一對一"關(guān)系更復(fù)雜一些。

預(yù)加載

GORM可以通過Preload預(yù)加載has many關(guān)聯(lián)的記錄。

自定義連接表

連接表可以說一個全功能的模型,支持soft Delete、鉤子、更多字段,就根其他模型一樣。您可以通過SetupJoinTable指定它,例如:
注意:自定義連接表要求外鍵是復(fù)合主鍵或復(fù)合唯一索引

type Person struct {ID        intName      stringAddresses []Address `gorm:"many2many:person_addresses;"`
}type Address struct {ID   uintName string
}type PersonAddress struct {PersonID  int `gorm:"primaryKey"`AddressID int `gorm:"primaryKey"`CreatedAt time.TimeDeletedAt gorm.DeletedAt
}func (PersonAddress) BeforeCreate(db *gorm.DB) error {// ...
}// 修改 Person 的 Addresses 字段的連接表為 PersonAddress
// PersonAddress 必須定義好所需的外鍵,否則會報錯
err := db.SetupJoinTable(&Person{}, "Addresses", &PersonAddress{})

解讀:
這段內(nèi)容解釋了在GORM中如何自定義"Many To Many"關(guān)系的連接表,并且如何為這個連接表添加額外的字段和功能,比如軟刪除(Soft Delete)和鉤子(Hooks)。通過這種方式,連接表不僅僅是用于存儲兩個模型之間關(guān)系的簡單表,而是可以成為一個全功能的模型,類似于其他的GORM模型。

自定義連接表的模型定義
Person模型
Person模型定義了一個Addresses字段,通過gorm:"many2many:person_addresses;"標簽指明和Address模型之間的多對多關(guān)系,并且指定使用person_addresses作為連接表。

Address模型
Address模型是簡單的,包含ID和Name字段。

PersonAddress連接表模型
PersonAddress是自定義的連接表模型,除了包含表示關(guān)系的PersonIDAddressID作為復(fù)合主鍵之外,還添加了CreatedAt和DeletedAt字段。DeletedAt字段支持GORM的軟刪除功能。
PersonAddress模型也可以定義方法如BeforeCreate鉤子,這在GORM中用于在創(chuàng)建記錄之前自動執(zhí)行特定邏輯。

自定義連接表的設(shè)置
通過db.SetupJoinTable(&Person{}, “Addresses”, &PersonAddress{})調(diào)用,GORM被指示使用PersonAddress作為Person和Address之間關(guān)系的連接表。這允許開發(fā)者利用GORM的高級功能,比如鉤子和軟刪除,在連接表上添加更多的字段。

注意事項
外鍵要求:自定義連接表要求外鍵是復(fù)合主鍵或復(fù)合唯一索引。這意味著在PersonAddress模型中,PersonID和AddressID需要被標記為primaryKey,以確保每個關(guān)系在表中是唯一的。

軟刪除:通過在連接表模型中添加DeletedAt字段,可以為連接表記錄實現(xiàn)軟刪除功能。這意味著,刪除操作會更新DeletedAt字段而不是從數(shù)據(jù)庫中物理刪除記錄,允許你保留和查詢被標記為刪除的關(guān)系。

鉤子:如BeforeCreate,允許你在創(chuàng)建連接表記錄之前執(zhí)行自定義邏輯,這與其他GORM模型的行為一致。

總結(jié):
通過自定義連接表,GORM提供了極大的靈活性和控制力,使得開發(fā)者可以更細致地管理模型之間的多對多關(guān)系,同時利用GORM提供的各種特性來增強連接表的功能。

外鍵約束

你可以通過標簽constraint配置OnUpdate、OnDelete實現(xiàn)外鍵約束,在使用GORM進行遷移時它會被創(chuàng)建,例如:

type User struct {gorm.ModelLanguages []Language `gorm:"many2many:user_speaks;"`
}type Language struct {Code string `gorm:"primarykey"`Name string
}// CREATE TABLE `user_speaks` (`user_id` integer,`language_code` text,PRIMARY KEY (`user_id`,`language_code`),CONSTRAINT `fk_user_speaks_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE SET NULL ON UPDATE CASCADE,CONSTRAINT `fk_user_speaks_language` FOREIGN KEY (`language_code`) REFERENCES `languages`(`code`) ON DELETE SET NULL ON UPDATE CASCADE);

你也可以在刪除記錄時通過Select來刪除many2many關(guān)系的記錄,查看Delete with Select獲取詳情。

復(fù)合外鍵

如果你的模型使用了復(fù)合主鍵,GORM會默認啟用復(fù)合外鍵。
你也可以覆蓋默認的外鍵,指定多個外鍵,只需要逗號分隔那些鍵名,例如:

type Tag struct {ID     uint   `gorm:"primaryKey"`Locale string `gorm:"primaryKey"`Value  string
}type Blog struct {ID         uint   `gorm:"primaryKey"`Locale     string `gorm:"primaryKey"`Subject    stringBody       stringTags       []Tag `gorm:"many2many:blog_tags;"`LocaleTags []Tag `gorm:"many2many:locale_blog_tags;ForeignKey:id,locale;References:id"`SharedTags []Tag `gorm:"many2many:shared_blog_tags;ForeignKey:id;References:id"`
}// 連接表:blog_tags
//   foreign key: blog_id, reference: blogs.id
//   foreign key: blog_locale, reference: blogs.locale
//   foreign key: tag_id, reference: tags.id
//   foreign key: tag_locale, reference: tags.locale// 連接表:locale_blog_tags
//   foreign key: blog_id, reference: blogs.id
//   foreign key: blog_locale, reference: blogs.locale
//   foreign key: tag_id, reference: tags.id// 連接表:shared_blog_tags
//   foreign key: blog_id, reference: blogs.id
//   foreign key: tag_id, reference: tags.id

解讀:
這段內(nèi)容解釋了在使用GORM處理復(fù)合主鍵時如何定義和自定義復(fù)合外鍵關(guān)系。復(fù)合主鍵是指使用兩個或更多的列來唯一標識表中的每行記錄。當模型使用復(fù)合主鍵時,GORM默認啟用復(fù)合外鍵來匹配這些復(fù)合主鍵。然而,GORM也提供了靈活性來覆蓋這些默認行為,允許指定自定義的外鍵組合。

復(fù)合主鍵與復(fù)合外鍵
在提供的例子中,Tag和Blog模型都使用了復(fù)合主鍵(ID和Locale),這意味著每個Tag和Blog的唯一性不僅僅由ID決定,還需要Locale來共同確定。

自定義外鍵關(guān)系
Blog模型的Tags字段
默認行為:對于Tags字段,GORM默認使用模型的復(fù)合主鍵(ID和Locale)作為復(fù)合外鍵。這意味著在blog_tags連接表中,會有四個外鍵blog_id和blog_locale用來引用Blog模型,tag_id和tag_locale用來引用Tag模型。

Blog模型的LocaleTags字段
自定義外鍵:通過ForeignKey:id,locale;References:id標簽,明確指定了使用Blog的ID和Locale作為外鍵,并且指定它們引用Tag模型的ID字段。這里似乎有一個小錯誤或遺漏,因為References應(yīng)該指向Tag模型的ID和Locale字段來正確映射復(fù)合外鍵。理論上,正確的標簽可能是ForeignKey:id,locale;References:id,locale。

Blog模型的SharedTags字段
簡化的外鍵關(guān)系:SharedTags字段示例通過ForeignKey:id;References:id標簽,只使用ID字段作為外鍵和引用。這在shared_blog_tags連接表中創(chuàng)建了一個簡化的關(guān)系,只包括blog_id和tag_id,沒有考慮Locale,這可能用于那些Locale不是區(qū)分共享標簽重要因素的場景。

連接表的結(jié)構(gòu)
blog_tags:這個連接表包含了所有四個外鍵,完整地表示了Blog和Tag之間復(fù)合主鍵的多對多關(guān)系。
locale_blog_tags:這個連接表應(yīng)該包含了Blog和Tag之間特定于語言的關(guān)聯(lián),但示例中的標簽定義可能有誤,理應(yīng)包含Locale的映射。
shared_blog_tags:僅基于ID的簡化多對多關(guān)系,適用于跨語言共享的標簽。

總結(jié)
通過這種方法,GORM提供了靈活的方式來定義和自定義復(fù)合外鍵,以及如何在多對多關(guān)系中使用它們。這使得開發(fā)者可以根據(jù)具體需求精確控制數(shù)據(jù)庫關(guān)系的結(jié)構(gòu),尤其是在涉及復(fù)合主鍵時。然而,在自定義外鍵和引用時需要小心確保標簽的正確性和一致性,以避免錯誤和混淆。

http://m.risenshineclean.com/news/61259.html

相關(guān)文章:

  • 找工作網(wǎng)站谷歌在線瀏覽入口
  • 自己做網(wǎng)站的過程搜索引擎seo是什么意思
  • 做商城網(wǎng)站需要備案嗎鄒平縣seo網(wǎng)頁優(yōu)化外包
  • 中山網(wǎng)站建設(shè)找丁生商城推廣軟文范文
  • 有效的網(wǎng)站建設(shè)百度怎么發(fā)布短視頻
  • 東營建筑信息網(wǎng)北京網(wǎng)絡(luò)seo經(jīng)理
  • wordpress 強制換行網(wǎng)站seo軟件
  • 學(xué)做課件的網(wǎng)站新媒體營銷推廣公司
  • 給我一個可以看片的免費seo排名官網(wǎng)
  • 網(wǎng)站建設(shè)的意義線上直播營銷策劃方案
  • 簡單的個人網(wǎng)站html網(wǎng)絡(luò)營銷第三版課本
  • 蘇州做商城網(wǎng)站設(shè)計快推廣app下載
  • 國外移動端網(wǎng)站模板杭州專業(yè)seo公司
  • 網(wǎng)站怎么做才被收錄快google play下載安裝
  • 做網(wǎng)站看網(wǎng)絡(luò)推廣計劃書
  • 智能小程序是什么河北seo技術(shù)培訓(xùn)
  • 西安企業(yè)網(wǎng)站建設(shè)seo是怎么優(yōu)化
  • 安陽網(wǎng)站制作哪家好七牛云
  • 網(wǎng)站設(shè)計制作的服務(wù)好不好做關(guān)鍵詞優(yōu)化的公司
  • 柳州做網(wǎng)站設(shè)計的公司中國互聯(lián)網(wǎng)域名注冊服務(wù)機構(gòu)
  • 做h網(wǎng)站怎么才能安全企業(yè)網(wǎng)址怎么申請
  • 深圳網(wǎng)站制作哪里找成都十大營銷策劃公司
  • 辛集專業(yè)網(wǎng)站建設(shè)seo博客網(wǎng)址
  • 百度站長平臺查詢軟件培訓(xùn)機構(gòu)
  • 昆明做網(wǎng)站哪家公司好大數(shù)據(jù)營銷系統(tǒng)多少錢
  • 手機網(wǎng)站設(shè)計立找億企邦夫唯老師seo
  • 給孩子做的飯網(wǎng)站網(wǎng)絡(luò)公關(guān)公司
  • 旅游網(wǎng)站開發(fā)背景及意義公司網(wǎng)站建設(shè)步驟
  • 日本親子游哪個網(wǎng)站做的好處寧波seo外包快速推廣
  • 做網(wǎng)站不掙錢鎮(zhèn)江優(yōu)化推廣