240 lines
4.9 KiB
Markdown
240 lines
4.9 KiB
Markdown
# 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", "<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`先创建数据库。
|
||
|
||
#### 插入实体
|
||
通过如下代码,可以插入实体:
|
||
```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
|
||
|
||
<img loading="lazy" src="https://entgo.io/images/assets/re_user_cars.png" alt="er-user-cars" class="img_ev3q" id="er-user-cars">
|
||
|
||
运行`go generate ./ent`后如下:
|
||
```bash
|