当前位置: 代码网 > it编程>前端脚本>Golang > go语言中使用ent做关联查询的示例详解

go语言中使用ent做关联查询的示例详解

2024年05月19日 Golang 我要评论
一、背景和意义go语言的ent框架是facebook开源的orm框架,是go语言开发中的常用框架,而关联查询又是日常开发中的常见数据库操作,故文本给出一个使用ent做关联查询的使用示例。二、引入ent

一、背景和意义

go语言的ent框架是facebook开源的orm框架,是go语言开发中的常用框架,而关联查询又是日常开发中的常见数据库操作,故文本给出一个使用ent做关联查询的使用示例。

二、引入ent

安装ent的命令为:

go install entgo.io/ent/cmd/ent@latest

找一个空目录作为项目目录,在目录下执行命令创建项目文件:

go mod init entdemo

执行命令之后,项目下添加了go.mod文件。

三、定义数据库实体

接下来创建ent数据库实体文件,一个实体是学生(student),一个实体是班级(class),命令为:

ent new class student

执行命令之后,项目下多了ent/schema/student.go和ent/schema/class.go两个文件。我们准备修改这两个文件,修改前先添加相关依赖:

go mod tidy

然后修改两个文件的内容,添加字段了关联关系。

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{ // 设置字段信息
      field.string("name").maxlen(50).comment("名称"),
      field.bool("sex").comment("性别"),
      field.int("age").comment("年龄"),
      field.int("class_id").comment("班级id"),
   }
}

// edges of the student.
func (student) edges() []ent.edge {
   return []ent.edge{ // 设置关联关系
      edge.from("class", class.type).
         ref("student").
         unique().
         field("class_id"). // 通过class_id字段关联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{     // 设置字段信息
      field.string("name").maxlen(50).comment("名称"),
      field.int("level").comment("级别"),
   }
}

// edges of the class.
func (class) edges() []ent.edge {
   return []ent.edge{     // 设置关联关系
      edge.to("student", student.type), // 表示一个班级可关联多个学生
   }
}

其中student与class存在n对1的关联关系,每个学生属于某个班级,一个班级可以包含多个学生,这一关联信息体现在student.go和class.go中的edges方法中。

接下来执行命令:

go generate ./ent

执行完之后,生成了ent相关的一些模板代码。

四、创建表结构

在项目下创建main.go文件:

package main

import (
   "context"
   "entdemo/ent"
   _ "github.com/go-sql-driver/mysql"
   "log"
)

func main() {
   // 连接数据库, 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数据库失败: %v", err)
   }
   defer client.close()

   // 根据实体类字段配置创建或更新数据库
   ctx := context.background()
   if err := client.schema.create(ctx); err != nil {
      log.fatalf("创建数据结构失败: %v", err)
   }
}

该文件中连接mysql数据,然后调用ent.client.schama.create方法创建数据表结构,执行该文件程序之前,mysql数据中是这样:

接下来执行main.go:

go run main.go

执行之后,程序创建了相关的数据表:

五、添加数据

创建create.go文件添加一些数据:

package main

import (
   "context"
   "entdemo/ent"
   _ "github.com/go-sql-driver/mysql"
   "log"
)

func main() {
   // 连接数据库, 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数据库失败: %v", err)
   }
   defer client.close()

   ctx := context.background()

   // 创建班级
   class3, err := client.class.create().setname("三班").setlevel(5).save(ctx)
   if err != nil {
      log.fatalf("创建班级失败:%v", err)
      return
   }
   class2, err := client.class.create().setname("二班").setlevel(6).save(ctx)
   if err != nil {
      log.fatalf("创建班级失败:%v", err)
      return
   }

   // 创建学生
   u1, err := client.student.create().
      setclass(class3).setname("小张").setsex(false).setage(12).save(ctx)
   if err != nil {
      log.fatalf("创建用户失败:%v", err)
      return
   }
   log.println("创建用户:", u1)

   u2, err := client.student.create().
      setclass(class3).setname("小李").setsex(true).setage(11).save(ctx)
   if err != nil {
      log.fatalf("创建用户失败:%v", err)
      return
   }
   log.println("创建用户:", u2)

   u3, err := client.student.create().
      setclass(class2).setname("小赵").setsex(true).setage(12).save(ctx)
   if err != nil {
      log.fatalf("创建用户失败:%v", err)
      return
   }
   log.println("创建用户:", u3)
}

这里需要注意的是,学生和班级之间存在关联关系,这里是在学生侧调用setclass方法设置当前学生所关联的班级实体。

接下来执行命令:

go run create.go

执行完之后,查数据库,可以看到students和classes表增加了一些数据。

六、查询数据

创建文件query.go:

package main

import (
   "context"
   "entdemo/ent"
   _ "github.com/go-sql-driver/mysql"
   "log"
)

func main() {
   // 连接数据库, 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数据库失败: %v", err)
   }
   defer client.close()

   ctx := context.background()
   ulist, err := client.student.query().withclass().all(ctx)
   if err != nil {
      log.fatalf("查询数据失败:%v", err)
      return
   }

   for _, v := range ulist {
      log.println("学生:", v, ",所在班级:", v.edges.class)
   }
}

这里需要注意的是,如果我们既要获取学生数据,又要获取每个学生所在班级的信息,那么需要关联查询students和classes表,代码中是通过调用withclass()方法实现的。在做关联查询之后,班级信息会存储在student实体的edges.class属性中。

运行命令:

go run query.go

终端将输出如下执行结果:

以上就是go语言中使用ent做关联查询的示例详解的详细内容,更多关于go ent关联查询的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com