特性开关
此框架提供了一系列代码生成特性,可以自行选择使用。
用法
特性开关可以通过 CLI 标志或作为参数提供给 gen
包。
CLI
go run entgo.io/ent/cmd/ent generate --feature privacy,entql ./ent/schema
Go
// +build ignore
package main
import (
"log"
"text/template"
"entgo.io/ent/entc"
"entgo.io/ent/entc/gen"
)
func main() {
err := entc.Generate("./schema", &gen.Config{
Features: []gen.Feature{
gen.FeaturePrivacy,
gen.FeatureEntQL,
},
Templates: []*gen.Template{
gen.MustParse(gen.NewTemplate("static").
Funcs(template.FuncMap{"title": strings.ToTitle}).
ParseFiles("template/static.tmpl")),
},
})
if err != nil {
log.Fatalf("running ent codegen: %v", err)
}
}
特性列表
隐私层
隐私层允许为数据库中实体的查询和更变操作配置隐私政策。
This option can added to a project using the --feature privacy
flag, and its full documentation exists in the privacy page.
EntQL过滤器
entql
配置项在运行时为不同的查询构造器提供了通用的动态筛选功能。
This option can be added to a project using the --feature entql
flag, and more information about it exists in the privacy page.
自动解决合并冲突
schema/snapshot
配置项告诉entc
(ent 代码生成) ,对最新结构 (schema) 生成一个快照,当用户的 结构 (schema) 不能构建时,自动使用生成的快照解决合并冲突。
This option can be added to a project using the --feature schema/snapshot
flag, but please see ent/ent/issues/852 to get more context about it.
Schema配置
使用sql/schemaconfig
配置项,你能给关系数据库中的对象定义别名,并将其映射到模型上。 当你的模型并不都生活在一个数据库下,而是根据 Schema 而有所不同,这很有用。
This option can be added to a project using the --feature sql/schemaconfig
flag. 在生成代码之后,你就可以使用新的配置项,比如:
c, err := ent.Open(dialect, conn, ent.AlternateSchema(ent.SchemaConfig{
User: "usersdb",
Car: "carsdb",
}))
c.User.Query().All(ctx) // SELECT * FROM `usersdb`.`users`
c.Car.Query().All(ctx) // SELECT * FROM `carsdb`.`cars`
Row-level Locks
The sql/lock
option lets configure row-level locking using the SQL SELECT ... FOR {UPDATE | SHARE}
syntax.
This option can be added to a project using the --feature sql/lock
flag.
tx, err := client.Tx(ctx)
if err != nil {
log.Fatal(err)
}
tx.Pet.Query().
Where(pet.Name(name)).
ForUpdate().
Only(ctx)
tx.Pet.Query().
Where(pet.ID(id)).
ForShare(
sql.WithLockTables(pet.Table),
sql.WithLockAction(sql.NoWait),
).
Only(ctx)
Custom SQL Modifiers
The sql/modifier
option lets add custom SQL modifiers to the builders and mutate the statements before they are executed.
This option can be added to a project using the --feature sql/modifier
flag.
Example 1
client.Pet.
Query().
Modify(func(s *sql.Selector) {
s.Select("SUM(LENGTH(name))")
}).
IntX(ctx)
The above code will produce the following SQL query:
SELECT SUM(LENGTH(name)) FROM `pet`
Example 2
var p1 []struct {
ent.Pet
NameLength int `sql:"length"`
}
client.Pet.Query().
Order(ent.Asc(pet.FieldID)).
Modify(func(s *sql.Selector) {
s.AppendSelect("LENGTH(name)")
}).
ScanX(ctx, &p1)
The above code will produce the following SQL query:
SELECT `pet`.*, LENGTH(name) FROM `pet` ORDER BY `pet`.`id` ASC
Example 3
var v []struct {
Count int `json:"count"`
Price int `json:"price"`
CreatedAt time.Time `json:"created_at"`
}
client.User.
Query().
Where(
user.CreatedAtGT(x),
user.CreatedAtLT(y),
).
Modify(func(s *sql.Selector) {
s.Select(
sql.As(sql.Count("*"), "count"),
sql.As(sql.Sum("price"), "price"),
sql.As("DATE(created_at)", "created_at"),
).
GroupBy("DATE(created_at)").
OrderBy(sql.Desc("DATE(created_at)"))
}).
ScanX(ctx, &v)
The above code will produce the following SQL query:
SELECT
COUNT(*) AS `count`,
SUM(`price`) AS `price`,
DATE(created_at) AS `created_at`
FROM
`users`
WHERE
`created_at` > x AND `created_at` < y
GROUP BY
DATE(created_at)
ORDER BY
DATE(created_at) DESC
Example 4
var gs []struct {
ent.Group
UsersCount int `sql:"users_count"`
}
client.Group.Query().
Order(ent.Asc(group.FieldID)).
Modify(func(s *sql.Selector) {
t := sql.Table(group.UsersTable)
s.LeftJoin(t).
On(
s.C(group.FieldID),
t.C(group.UsersPrimaryKey[1]),
).
// Append the "users_count" column to the selected columns.
AppendSelect(
sql.As(sql.Count(t.C(group.UsersPrimaryKey[1])), "users_count"),
).
GroupBy(s.C(group.FieldID))
}).
ScanX(ctx, &gs)
The above code will produce the following SQL query:
SELECT
`groups`.*,
COUNT(`t1`.`group_id`) AS `users_count`
FROM
`groups` LEFT JOIN `user_groups` AS `t1`
ON
`groups`.`id` = `t1`.`group_id`
GROUP BY
`groups`.`id`
ORDER BY
`groups`.`id` ASC
Upsert
The sql/upsert
option lets configure upsert and bulk-upsert logic using the SQL ON CONFLICT
/ ON DUPLICATE KEY
syntax. For full documentation, go to the Upsert API.
This option can be added to a project using the --feature sql/upsert
flag.
// Use the new values that were set on create.
id, err := client.User.
Create().
SetAge(30).
SetName("Ariel").
OnConflict().
UpdateNewValues().
ID(ctx)
// In PostgreSQL, the conflict target is required.
err := client.User.
Create().
SetAge(30).
SetName("Ariel").
OnConflictColumns(user.FieldName).
UpdateNewValues().
Exec(ctx)
// Bulk upsert is also supported.
client.User.
CreateBulk(builders...).
OnConflict(
sql.ConflictWhere(...),
sql.UpdateWhere(...),
).
UpdateNewValues().
Exec(ctx)
// INSERT INTO "users" (...) VALUES ... ON CONFLICT WHERE ... DO UPDATE SET ... WHERE ...