# ent ## Introduction ent是一个简单、功能强大的entity framework。下面,将会是一个ent的使用示例。 ### init project ```bash go mod init entdemo ``` ### 创建schema 在entdemo目录下运行 ```bash go run -mod=mod entgo.io/ent/cmd/ent new User ``` 上述命令会为`User`创建schema,创建位置位于`entdemo/ent/schema`目录下,`entdemo/ent/schema/user.go`文件内容如下: ```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`内容为如下: ```go // 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`: ```bash 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 ```golang package main import ( "context" "log" "entdemo/ent" _ "github.com/go-sql-driver/mysql" ) func main() { client, err := ent.Open("mysql", ":@tcp(:)/?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`先创建数据库。 #### 插入实体 通过如下代码,可以插入实体: ```golang 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 } ``` ### 查询实体 查询实体可以通过如下代码实现: ```golang 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 } ``` ### 添加关联关系 另外创建两个实体`Car`和`Group` ```bash go run -mod=mod entgo.io/ent/cmd/ent new Car Group ``` 修改Car实体如下 ```golang 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实体如下: ```golang 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`方法 ```golang 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`后如下: ```bash