快速入门
Last updated
go get github.com/facebookincubator/ent/cmd/entcentc init User// <project>/ent/schema/user.go
package schema
import "github.com/facebookincubator/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
}package schema
import (
"github.com/facebookincubator/ent"
"github.com/facebookincubator/ent/schema/field"
)
// Fields of the User.
func (User) Fields() []ent.Field {
return []ent.Field{
field.Int("age").
Positive(),
field.String("name").
Default("unknown"),
}
}entc generate ./ent/schemaent
├── client.go
├── config.go
├── context.go
├── ent.go
├── example_test.go
├── migrate
│ ├── migrate.go
│ └── schema.go
├── predicate
│ └── predicate.go
├── schema
│ └── user.go
├── tx.go
├── user
│ ├── user.go
│ └── where.go
├── user.go
├── user_create.go
├── user_delete.go
├── user_query.go
└── user_update.gopackage main
import (
"log"
"<project>/ent"
_ "github.com/mattn/go-sqlite3"
)
func main() {
client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
if err != nil {
log.Fatalf("failed opening connection to sqlite: %v", err)
}
defer client.Close()
// 运行自动迁移工具。
if err := client.Schema.Create(context.Background()); err != nil {
log.Fatalf("failed creating schema resources: %v", err)
}
}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: %v", err)
}
log.Println("user was created: ", u)
return u, nil
}package main
import (
"log"
"<project>/ent"
"<project>/ent/user"
)
func QueryUser(ctx context.Context, client *ent.Client) (*ent.User, error) {
u, err := client.User.
Query().
Where(user.NameEQ("a8m")).
// `Only` 会查询失败,
// 当未找到用户或找到多个(大于一个)用户时,
Only(ctx)
if err != nil {
return nil, fmt.Errorf("failed querying user: %v", err)
}
log.Println("user returned: ", u)
return u, nil
}entc init Car Groupimport (
"regexp"
"github.com/facebookincubator/ent"
"github.com/facebookincubator/ent/schema/field"
)
// Fields of the Car (car.go).
func (Car) Fields() []ent.Field {
return []ent.Field{
field.String("model"),
field.Time("registered_at"),
}
}
// Fields of the Group (group.go).
func (Group) Fields() []ent.Field {
return []ent.Field{
field.String("name").
// 正则验证 group 名.
Match(regexp.MustCompile("[a-zA-Z_]+$")),
}
} import (
"log"
"github.com/facebookincubator/ent"
"github.com/facebookincubator/ent/schema/edge"
)
// Edges of the User.
func (User) Edges() []ent.Edge {
return []ent.Edge{
edge.To("cars", Car.Type),
}
}func CreateCars(ctx context.Context, client *ent.Client) (*ent.User, error) {
// 买一辆 "Tesla".
tesla, err := client.Car.
Create().
SetModel("Tesla").
SetRegisteredAt(time.Now()).
Save(ctx)
if err != nil {
return nil, fmt.Errorf("failed creating car: %v", err)
}
// 买一辆 "Ford".
ford, err := client.Car.
Create().
SetModel("Ford").
SetRegisteredAt(time.Now()).
Save(ctx)
if err != nil {
return nil, fmt.Errorf("failed creating car: %v", err)
}
log.Println("car was created: ", ford)
// 创建一个用户,并给他添加两辆车。
a8m, err := client.User.
Create().
SetAge(30).
SetName("a8m").
AddCars(tesla, ford).
Save(ctx)
if err != nil {
return nil, fmt.Errorf("failed creating user: %v", err)
}
log.Println("user was created: ", a8m)
return a8m, nil
}import (
"log"
"<project>/ent"
"<project>/ent/car"
)
func QueryCars(ctx context.Context, a8m *ent.User) error {
cars, err := a8m.QueryCars().All(ctx)
if err != nil {
return fmt.Errorf("failed querying user cars: %v", err)
}
log.Println("returned cars:", cars)
// 筛选特定车型。
ford, err := a8m.QueryCars().
Where(car.ModelEQ("Ford")).
Only(ctx)
if err != nil {
return fmt.Errorf("failed querying user cars: %v", err)
}
log.Println(ford)
return nil
}import (
"log"
"github.com/facebookincubator/ent"
"github.com/facebookincubator/ent/schema/edge"
)
// Edges of the Car.
func (Car) Edges() []ent.Edge {
return []ent.Edge{
// 创建一个类型为 `User` 名为 "owner" 的逆边
// 并且使用 `Ref` 方法明确的将其引用至(User 模式中的) "cars" 边
edge.From("owner", User.Type).
Ref("cars").
// 指定该边为唯一,确保一辆车只有一个车主。
Unique(),
}
}import (
"log"
"<project>/ent"
)
func QueryCarUsers(ctx context.Context, a8m *ent.User) error {
cars, err := a8m.QueryCars().All(ctx)
if err != nil {
return fmt.Errorf("failed querying user cars: %v", err)
}
// 查询逆边。
for _, ca := range cars {
owner, err := ca.QueryOwner().Only(ctx)
if err != nil {
return fmt.Errorf("failed querying car %q owner: %v", ca.Model, err)
}
log.Printf("car %q owner: %q\n", ca.Model, owner.Name)
}
return nil
} import (
"log"
"github.com/facebookincubator/ent"
"github.com/facebookincubator/ent/schema/edge"
)
// Edges of the Group.
func (Group) Edges() []ent.Edge {
return []ent.Edge{
edge.To("users", User.Type),
}
} import (
"log"
"github.com/facebookincubator/ent"
"github.com/facebookincubator/ent/schema/edge"
)
// Edges of the User.
func (User) Edges() []ent.Edge {
return []ent.Edge{
edge.To("cars", Car.Type),
// 创建一个类型为 `Group` 名为 "groups" 的逆边
edge.From("groups", Group.Type).
// 并且使用 `Ref` 方法明确的将其引用至(Group 模式中的) "users" 边
Ref("users"),
}
}entc generate ./ent/schemafunc CreateGraph(ctx context.Context, client *ent.Client) error {
// 首先创建一个用户
a8m, err := client.User.
Create().
SetAge(30).
SetName("Ariel").
Save(ctx)
if err != nil {
return err
}
neta, err := client.User.
Create().
SetAge(28).
SetName("Neta").
Save(ctx)
if err != nil {
return err
}
// 然后,创建汽车,并指定其拥有者(车主)。
_, err = client.Car.
Create().
SetModel("Tesla").
SetRegisteredAt(time.Now()). // 忽略图中的时间
SetOwner(a8m). // 指定车主为 Ariel.
Save(ctx)
if err != nil {
return err
}
_, err = client.Car.
Create().
SetModel("Mazda").
SetRegisteredAt(time.Now()). // 忽略图中的时间
SetOwner(a8m). // 指定车主为 Ariel.
Save(ctx)
if err != nil {
return err
}
_, err = client.Car.
Create().
SetModel("Ford").
SetRegisteredAt(time.Now()). // 忽略图中的时间
SetOwner(neta). // 指定车主为 Neta.
Save(ctx)
if err != nil {
return err
}
// 创建群组,并同时添加用户。
_, err = client.Group.
Create().
SetName("GitLab").
AddUsers(neta, a8m).
Save(ctx)
if err != nil {
return err
}
_, err = client.Group.
Create().
SetName("GitHub").
AddUsers(a8m).
Save(ctx)
if err != nil {
return err
}
log.Println("The graph was created successfully")
return nil
} import (
"log"
"<project>/ent"
"<project>/ent/group"
)
func QueryGithub(ctx context.Context, client *ent.Client) error {
cars, err := client.Group.
Query().
Where(group.Name("GitHub")). // (Group(Name=GitHub),)
QueryUsers(). // (User(Name=Ariel, Age=30),)
QueryCars(). // (Car(Model=Tesla, RegisteredAt=<Time>), Car(Model=Mazda, RegisteredAt=<Time>),)
All(ctx)
if err != nil {
return fmt.Errorf("failed getting cars: %v", err)
}
log.Println("cars returned:", cars)
// Output: (Car(Model=Tesla, RegisteredAt=<Time>), Car(Model=Mazda, RegisteredAt=<Time>),)
return nil
} import (
"log"
"<project>/ent"
"<project>/ent/car"
)
func QueryArielCars(ctx context.Context, client *ent.Client) error {
// Get "Ariel" from previous steps.
a8m := client.User.
Query().
Where(
user.HasCars(),
user.Name("Ariel"),
).
OnlyX(ctx)
cars, err := a8m. // 首先获取群组,Ariel 所属的群主为:
QueryGroups(). // (Group(Name=GitHub), Group(Name=GitLab),)
QueryUsers(). // (User(Name=Ariel, Age=30), User(Name=Neta, Age=28),)
QueryCars(). //
Where( //
car.Not( // 获取 Neta 和 Ariel 的汽车
car.ModelEQ("Mazda"), // 但是这里过滤掉了名为 "Mazda" 的汽车
), //
). //
All(ctx)
if err != nil {
return fmt.Errorf("failed getting cars: %v", err)
}
log.Println("cars returned:", cars)
// Output: (Car(Model=Tesla, RegisteredAt=<Time>), Car(Model=Ford, RegisteredAt=<Time>),)
return nil
} import (
"log"
"<project>/ent"
"<project>/ent/group"
)
func QueryGroupWithUsers(ctx context.Context, client *ent.Client) error {
groups, err := client.Group.
Query().
Where(group.HasUsers()).
All(ctx)
if err != nil {
return fmt.Errorf("failed getting groups: %v", err)
}
log.Println("groups returned:", groups)
// Output: (Group(Name=GitHub), Group(Name=GitLab),)
return nil
}