# entgo 特性开关 --- 此框架提供了一系列代码生成特性,可以自行选择使用。 ## 用法 特性开关可以通过 CLI 标志或作为参数提供给 gen 包。 ### CLI ```shell go run entgo.io/ent/cmd/ent generate --feature privacy,entql,schema/snapshot,sql/schemaconfig,sql/lock,upsert ./ent/schema ``` ### Go ```golang // +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) } } ``` ## 特性列表 ### 隐私层 - 隐私层允许为数据库中实体的查询和更变操作配置隐私政策(通俗来讲就是设定角色与权限,让每个人只能给看到属于自己的东西)。 ### EntQL过滤器 - entql配置项在运行时为不同的查询构造器提供了通用的动态筛选功能。 ### 自动解决合并冲突 - schema/snapshot配置项告诉entc (ent 代码生成) ,对最新结构 (schema) 生成一个快照,当用户的 结构 (schema) 不能构建时,自动使用生成的快照解决合并冲突。 ### Schema配置 - 使用sql/schemaconfig 配置项,你能给关系数据库中的对象定义别名,并将其映射到模型上。 当你的模型并不都生活在一个数据库下,而是根据 Schema 而有所不同,这很有用。 在生成代码之后,你就可以使用新的配置项,比如: ```golang 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` ``` ### 行级锁定 sql/lock 选项允许使用 SQL SELECT ... FOR {UPDATE OR SHARE } 配置行级锁定语法 。 <table><tr><td bgcolor=yellow>背景色yellow</td></tr></table> ```golang 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) ``` ### 自定义 SQL 修饰符 - sql/modifier 选项允许将自定义 SQL 修饰符添加到构建器并在执行语句之前对其进行变异。 ```golang // SELECT SUM(LENGTH(name)) FROM `pet`; client.Pet. Query(). Modify(func(s *sql.Selector) { s.Select("SUM(LENGTH(name))") }).IntX(ctx) // SELECT `pet`.*, LENGTH(name) FROM `pet` ORDER BY `pet`.`id` ASC; 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) /* 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; */ 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) /* 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; */ 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) ``` ### Upsert - sql/upsert 选项允许使用 SQL ON CONFLICT / ON DUPLICATE KEY 语法配置 upsert 和 bulk-upsert 逻辑。 如需完整文档,请访问 Upsert API。 - ```golang // 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 .. ``` ###### tags: `Golang` `entgo`