Files
rikako-note/Golang/ent.md
2025-02-18 20:56:24 +08:00

4.9 KiB
Raw Permalink Blame History

ent

Introduction

ent是一个简单、功能强大的entity framework。下面将会是一个ent的使用示例。

init project

go mod init entdemo

创建schema

在entdemo目录下运行

go run -mod=mod entgo.io/ent/cmd/ent new User

上述命令会为User创建schema创建位置位于entdemo/ent/schema目录下,entdemo/ent/schema/user.go文件内容如下:

package schema

import "entgo.io/ent"

// User holds the schema definition for the User entity.
type User struct {
	ent.Schema
}

// Fields of the User.
func (User) Fields() []ent.Field {
	return nil
}

// Edges of the User.
func (User) Edges() []ent.Edge {
	return nil
}

向User实体中添加字段

可以向User中添加两个字段修改Field内容为如下:

// Fields of the User.
func (User) Fields() []ent.Field {
    return []ent.Field{
        field.Int("age").
            Positive(),
        field.String("name").
            Default("unknown"),
    }
}

go generate

之后,可以调用go generate:

go generate ./ent

产生内容如下:

ent
├── client.go
├── config.go
├── context.go
├── ent.go
├── generate.go
├── mutation.go
... truncated
├── schema
│   └── user.go
├── tx.go
├── user
│   ├── user.go
│   └── where.go
├── user.go
├── user_create.go
├── user_delete.go
├── user_query.go
└── user_update.go

创建表并插入实体

创建表

在执行完上述步骤后可以通过如下代码来创建table

package main

import (
    "context"
    "log"

    "entdemo/ent"

    _ "github.com/go-sql-driver/mysql"
)

func main() {
    client, err := ent.Open("mysql", "<user>:<pass>@tcp(<host>:<port>)/<database>?parseTime=True")
    if err != nil {
        log.Fatalf("failed opening connection to mysql: %v", err)
    }
    defer client.Close()
    // Run the auto migration tool.
    if err := client.Schema.Create(context.Background()); err != nil {
        log.Fatalf("failed creating schema resources: %v", err)
    }
}

在执行上述代码前,需要先通过create database xxx先创建数据库。

插入实体

通过如下代码,可以插入实体:

entdemo/start.go
func CreateUser(ctx context.Context, client *ent.Client) (*ent.User, error) {
    u, err := client.User.
        Create().
        SetAge(30).
        SetName("a8m").
        Save(ctx)
    if err != nil {
        return nil, fmt.Errorf("failed creating user: %w", err)
    }
    log.Println("user was created: ", u)
    return u, nil
}

查询实体

查询实体可以通过如下代码实现:

func QueryUser(ctx context.Context, client *ent.Client) (ul []*ent.User, err error) {
	ul, err = client.User.
		Query().
		Where(
			user.Age(30),
			user.Name("a8m"),
		).All(ctx)
	if err != nil {
		log.Errorf("failed querying user: %v", err)
	}
	return
}

添加关联关系

另外创建两个实体CarGroup

go run -mod=mod entgo.io/ent/cmd/ent new Car Group

修改Car实体如下

package schema

import (
	"entgo.io/ent"
	"entgo.io/ent/schema/field"
)

// Car holds the schema definition for the Car entity.
type Car struct {
	ent.Schema
}

// Fields of the Car.
func (Car) Fields() []ent.Field {
	return []ent.Field{
		field.String("model"),
		field.Time("registered_at"),
	}
}

// Edges of the Car.
func (Car) Edges() []ent.Edge {
	return nil
}

修改Group实体如下

package schema

import (
	"entgo.io/ent"
	"entgo.io/ent/schema/field"
	"regexp"
)

// Group holds the schema definition for the Group entity.
type Group struct {
	ent.Schema
}

// Fields of the Group.
func (Group) Fields() []ent.Field {
	return []ent.Field{
		field.String("name").
			// Regexp validation for group name.
			Match(regexp.MustCompile("[a-zA-Z_]+$")),
	}
}

// Edges of the Group.
func (Group) Edges() []ent.Edge {
	return nil
}

并修改User实体如下为其新增Edges方法

package schema

import (
	"entgo.io/ent"
	"entgo.io/ent/schema/edge"
	"entgo.io/ent/schema/field"
)

// User holds the schema definition for the User entity.
type User struct {
	ent.Schema
}

// Fields of the User.
func (User) Fields() []ent.Field {
	return []ent.Field{
		field.Int("age").Positive(),
		field.String("name").Default("unknown"),
	}
}

// Edges of the User.
func (User) Edges() []ent.Edge {
	return []ent.Edge{
		edge.To("cars", Car.Type),
	}
}

可知Car和User实体的关系如下图所示

  • 一个user可以拥有多个car
er-user-cars

运行go generate ./ent后如下: