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

 更新时间:2024年02月26日 08:45:37   作者:qinyuan15  
go语言的ent框架是facebook开源的ORM框架,是go语言开发中的常用框架,而关联查询又是日常开发中的常见数据库操作,故文本给出一个使用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关联查询的资料请关注脚本之家其它相关文章!

相关文章

  • golang 字符串拼接性能的对比分析

    golang 字符串拼接性能的对比分析

    这篇文章主要介绍了golang 字符串拼接性能的对比分析,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Go+Kafka实现延迟消息的实现示例

    Go+Kafka实现延迟消息的实现示例

    本文主要介绍了Go+Kafka实现延迟消息的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • 关于go get 下载第三方包存储路径问题

    关于go get 下载第三方包存储路径问题

    这篇文章主要介绍了关于go get 下载第三方包存储路径问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • 一文带你掌握掌握 Golang结构体与方法

    一文带你掌握掌握 Golang结构体与方法

    在 Golang 中,结构体和方法是实现面向对象编程的重要组成部分,也是 Golang 的核心概念之一。在本篇文章中,我们将深入介绍 Golang 结构体与方法的概念、使用方法以及相关的编程技巧和最佳实践
    2023-04-04
  • 利用Golang实现TCP连接的双向拷贝详解

    利用Golang实现TCP连接的双向拷贝详解

    公司中遇到了一个使用golang编写的agent程序,所以这篇文章主要给大家介绍了关于利用Go如何实现TCP连接的双向拷贝的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考,下面随着小编来一起看看吧。
    2017-09-09
  • golang多次读取http request body的问题分析

    golang多次读取http request body的问题分析

    这篇文章主要给大家分析了golang多次读取http request body的问题,文中通过代码示例和图文介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-01-01
  • go语言通过odbc访问Sql Server数据库的方法

    go语言通过odbc访问Sql Server数据库的方法

    这篇文章主要介绍了go语言通过odbc访问Sql Server数据库的方法,实例分析了Go语言通过odbc连接与查SQL Server询数据库的技巧,需要的朋友可以参考下
    2015-03-03
  • Go函数使用(函数定义、函数声明、函数调用等)

    Go函数使用(函数定义、函数声明、函数调用等)

    本文主要介绍了Go函数使用,包括函数定义、函数声明、函数调用、可变参数函数、匿名函数、递归函数、高阶函数等,感兴趣的可以了解一下
    2023-11-11
  • 基于微服务框架go-micro开发gRPC应用程序

    基于微服务框架go-micro开发gRPC应用程序

    这篇文章介绍了基于微服务框架go-micro开发gRPC应用程序的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • Go语言包管理工具dep的安装与使用

    Go语言包管理工具dep的安装与使用

    godep是解决包依赖的管理工具,下面这篇文章主要给大家介绍了关于Go语言包管理工具dep的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-07-07

最新评论