go語言中使用ent做關(guān)聯(lián)查詢的示例詳解
一、背景和意義
go語言的ent框架是facebook開源的ORM框架,是go語言開發(fā)中的常用框架,而關(guān)聯(lián)查詢又是日常開發(fā)中的常見數(shù)據(jù)庫操作,故文本給出一個(gè)使用ent做關(guān)聯(lián)查詢的使用示例。
二、引入ent
安裝ent的命令為:
go install entgo.io/ent/cmd/ent@latest
找一個(gè)空目錄作為項(xiàng)目目錄,在目錄下執(zhí)行命令創(chuàng)建項(xiàng)目文件:
go mod init entdemo
執(zhí)行命令之后,項(xiàng)目下添加了go.mod文件。
三、定義數(shù)據(jù)庫實(shí)體
接下來創(chuàng)建ent數(shù)據(jù)庫實(shí)體文件,一個(gè)實(shí)體是學(xué)生(Student),一個(gè)實(shí)體是班級(jí)(Class),命令為:
ent new Class Student
執(zhí)行命令之后,項(xiàng)目下多了ent/schema/student.go和ent/schema/class.go兩個(gè)文件。我們準(zhǔn)備修改這兩個(gè)文件,修改前先添加相關(guān)依賴:
go mod tidy
然后修改兩個(gè)文件的內(nèi)容,添加字段了關(guān)聯(lián)關(guān)系。
ent/schema/student.go:
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
)
// Student holds the schema definition for the Student entity.
type Student struct {
ent.Schema
}
// Fields of the Student.
func (Student) Fields() []ent.Field {
return []ent.Field{ // 設(shè)置字段信息
field.String("name").MaxLen(50).Comment("名稱"),
field.Bool("sex").Comment("性別"),
field.Int("age").Comment("年齡"),
field.Int("class_id").Comment("班級(jí)ID"),
}
}
// Edges of the Student.
func (Student) Edges() []ent.Edge {
return []ent.Edge{ // 設(shè)置關(guān)聯(lián)關(guān)系
edge.From("class", Class.Type).
Ref("student").
Unique().
Field("class_id"). // 通過class_id字段關(guān)聯(lián)class表
Required(),
}
}
ent/schema/class.go:
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
)
// Class holds the schema definition for the Class entity.
type Class struct {
ent.Schema
}
// Fields of the Class.
func (Class) Fields() []ent.Field {
return []ent.Field{ // 設(shè)置字段信息
field.String("name").MaxLen(50).Comment("名稱"),
field.Int("level").Comment("級(jí)別"),
}
}
// Edges of the Class.
func (Class) Edges() []ent.Edge {
return []ent.Edge{ // 設(shè)置關(guān)聯(lián)關(guān)系
edge.To("student", Student.Type), // 表示一個(gè)班級(jí)可關(guān)聯(lián)多個(gè)學(xué)生
}
}
其中student與class存在N對(duì)1的關(guān)聯(lián)關(guān)系,每個(gè)學(xué)生屬于某個(gè)班級(jí),一個(gè)班級(jí)可以包含多個(gè)學(xué)生,這一關(guān)聯(lián)信息體現(xiàn)在student.go和class.go中的Edges方法中。
接下來執(zhí)行命令:
go generate ./ent
執(zhí)行完之后,生成了ent相關(guān)的一些模板代碼。
四、創(chuàng)建表結(jié)構(gòu)
在項(xiàng)目下創(chuàng)建main.go文件:
package main
import (
"context"
"entdemo/ent"
_ "github.com/go-sql-driver/mysql"
"log"
)
func main() {
// 連接數(shù)據(jù)庫, mysql連接串格式:username:password@(ipAddress)/databaseName?charset=utf8
URL := "test_user:123456@(127.0.0.1)/test?charset=utf8"
client, err := ent.Open("mysql", URL)
if err != nil {
log.Fatalf("連接mysql數(shù)據(jù)庫失敗: %v", err)
}
defer client.Close()
// 根據(jù)實(shí)體類字段配置創(chuàng)建或更新數(shù)據(jù)庫
ctx := context.Background()
if err := client.Schema.Create(ctx); err != nil {
log.Fatalf("創(chuàng)建數(shù)據(jù)結(jié)構(gòu)失敗: %v", err)
}
}
該文件中連接mysql數(shù)據(jù),然后調(diào)用ent.Client.Schama.Create方法創(chuàng)建數(shù)據(jù)表結(jié)構(gòu),執(zhí)行該文件程序之前,mysql數(shù)據(jù)中是這樣:

接下來執(zhí)行main.go:
go run main.go
執(zhí)行之后,程序創(chuàng)建了相關(guān)的數(shù)據(jù)表:



五、添加數(shù)據(jù)
創(chuàng)建create.go文件添加一些數(shù)據(jù):
package main
import (
"context"
"entdemo/ent"
_ "github.com/go-sql-driver/mysql"
"log"
)
func main() {
// 連接數(shù)據(jù)庫, mysql連接串格式:username:password@(ipAddress)/databaseName?charset=utf8
URL := "test_user:123456@(127.0.0.1)/test?charset=utf8"
client, err := ent.Open("mysql", URL)
if err != nil {
log.Fatalf("連接mysql數(shù)據(jù)庫失敗: %v", err)
}
defer client.Close()
ctx := context.Background()
// 創(chuàng)建班級(jí)
class3, err := client.Class.Create().SetName("三班").SetLevel(5).Save(ctx)
if err != nil {
log.Fatalf("創(chuàng)建班級(jí)失敗:%v", err)
return
}
class2, err := client.Class.Create().SetName("二班").SetLevel(6).Save(ctx)
if err != nil {
log.Fatalf("創(chuàng)建班級(jí)失?。?v", err)
return
}
// 創(chuàng)建學(xué)生
u1, err := client.Student.Create().
SetClass(class3).SetName("小張").SetSex(false).SetAge(12).Save(ctx)
if err != nil {
log.Fatalf("創(chuàng)建用戶失敗:%v", err)
return
}
log.Println("創(chuàng)建用戶:", u1)
u2, err := client.Student.Create().
SetClass(class3).SetName("小李").SetSex(true).SetAge(11).Save(ctx)
if err != nil {
log.Fatalf("創(chuàng)建用戶失?。?v", err)
return
}
log.Println("創(chuàng)建用戶:", u2)
u3, err := client.Student.Create().
SetClass(class2).SetName("小趙").SetSex(true).SetAge(12).Save(ctx)
if err != nil {
log.Fatalf("創(chuàng)建用戶失敗:%v", err)
return
}
log.Println("創(chuàng)建用戶:", u3)
}
這里需要注意的是,學(xué)生和班級(jí)之間存在關(guān)聯(lián)關(guān)系,這里是在學(xué)生側(cè)調(diào)用SetClass方法設(shè)置當(dāng)前學(xué)生所關(guān)聯(lián)的班級(jí)實(shí)體。
接下來執(zhí)行命令:
go run create.go
執(zhí)行完之后,查數(shù)據(jù)庫,可以看到students和classes表增加了一些數(shù)據(jù)。
六、查詢數(shù)據(jù)
創(chuàng)建文件query.go:
package main
import (
"context"
"entdemo/ent"
_ "github.com/go-sql-driver/mysql"
"log"
)
func main() {
// 連接數(shù)據(jù)庫, mysql連接串格式:username:password@(ipAddress)/databaseName?charset=utf8
URL := "test_user:123456@(127.0.0.1)/test?charset=utf8"
client, err := ent.Open("mysql", URL)
if err != nil {
log.Fatalf("連接mysql數(shù)據(jù)庫失敗: %v", err)
}
defer client.Close()
ctx := context.Background()
uList, err := client.Student.Query().WithClass().All(ctx)
if err != nil {
log.Fatalf("查詢數(shù)據(jù)失?。?v", err)
return
}
for _, v := range uList {
log.Println("學(xué)生:", v, ",所在班級(jí):", v.Edges.Class)
}
}
這里需要注意的是,如果我們既要獲取學(xué)生數(shù)據(jù),又要獲取每個(gè)學(xué)生所在班級(jí)的信息,那么需要關(guān)聯(lián)查詢students和classes表,代碼中是通過調(diào)用WithClass()方法實(shí)現(xiàn)的。在做關(guān)聯(lián)查詢之后,班級(jí)信息會(huì)存儲(chǔ)在Student實(shí)體的Edges.Class屬性中。
運(yùn)行命令:
go run query.go
終端將輸出如下執(zhí)行結(jié)果:

以上就是go語言中使用ent做關(guān)聯(lián)查詢的示例詳解的詳細(xì)內(nèi)容,更多關(guān)于go ent關(guān)聯(lián)查詢的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
解決golang在import自己的包報(bào)錯(cuò)的問題
這篇文章主要介紹了解決golang在import自己的包報(bào)錯(cuò)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-04-04
Golang?統(tǒng)計(jì)字符串中數(shù)字字母數(shù)量的實(shí)現(xiàn)方法
這篇文章主要介紹了Golang?統(tǒng)計(jì)字符串中數(shù)字字母數(shù)量,本文給出了兩種從字符串獲取數(shù)字與字母數(shù)量的方法,分別是ASCII 碼值和正則表達(dá)式,需要的朋友可以參考下2022-06-06
探索Golang實(shí)現(xiàn)Redis持久化AOF實(shí)例
這篇文章主要為大家介紹了Golang實(shí)現(xiàn)Redis持久化AOF實(shí)例探索,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
Golang使用crypto/ed25519實(shí)現(xiàn)數(shù)字簽名和驗(yàn)證
本文將深入探討如何在?Golang?中使用?crypto/ed25519?進(jìn)行數(shù)字簽名和驗(yàn)證,我們將從基本原理開始,逐步引導(dǎo)讀者了解生成密鑰對(duì)、進(jìn)行數(shù)字簽名,以及驗(yàn)證簽名的具體過程,希望對(duì)大家有所幫助2024-02-02

