type Querier interface { // SELECT * FROM @@table WHERE id=@id GetByID(id int) (gen.T, error) // returns struct and error
// SELECT * FROM @@table WHERE id=@id GetByID(id int) gen.T // returns data as struct
// SELECT * FROM @@table WHERE id=@id GetByID(id int) (gen.M, error) // returns map and error
// INSERT INTO @@table (name, age) VALUES (@name, @age) InsertValue(name string, age int) (gen.RowsAffected, error) // returns affected rows count and error }
这些基本类型可以与其他符号组合使用,例如 *、[]
type Querier interface { // SELECT * FROM @@table WHERE id=@id GetByID(id int) (*gen.T, error) // returns data as pointer and error
// SELECT * FROM @@table WHERE id=@id GetByID(id int) (*[]gen.T, error) // returns data as pointer of slice and error
// SELECT * FROM @@table WHERE id=@id GetByID(id int) ([]*gen.T, error) // returns data as slice of pointer and error
// SELECT * FROM @@table WHERE id=@id GetByID(id int) ([]gen.M, error) // returns data as slice of map and error }
模板占位符
Gen 提供了一些占位符来生成动态且安全的 SQL
名称
描述
@@table
转义并引用的表名
@@<name>
来自参数的转义并引用的表/列名
@<name>
来自参数的 SQL 查询参数
例如
type Filter interface { // SELECT * FROM @@table WHERE @@column=@value FilterWithColumn(column string, value string) (gen.T, error) }
// Apply the `Filter` interface to `User`, `Company` g.ApplyInterface(func(Filter) {}, model.User{}, model.Company{})
生成代码后,您可以在应用程序中像这样使用它。
import"your_project/query"
funcmain() { user, err := query.User.FilterWithColumn("name", "jinzhu") // similar like db.Exec("SELECT * FROM `users` WHERE `name` = ?", "jinzhu")
company, err := query.Company.FilterWithColumn("name", "tiktok") // similar like db.Exec("SELECT * FROM `companies` WHERE `name` = ?", "tiktok") }
模板表达式
Gen 为动态条件 SQL 提供了强大的表达式支持,目前支持以下表达式
if/else
where
set
for
if/else
if/else 表达式允许使用 golang 语法作为条件,可以这样写
{{if cond1}} // do something here {{elseif cond2}} // do something here {{else}} // do something here {{end}}
例如
type Querier interface { // SELECT * FROM users WHERE // {{if name !=""}} // username=@name AND // {{end}} // role="admin" QueryWith(name string) (gen.T,error) }
更复杂的例子
type Querier interface { // SELECT * FROM users // {{if user != nil}} // {{if user.ID > 0}} // WHERE id=@user.ID // {{else if user.Name != ""}} // WHERE username=@user.Name // {{end}} // {{end}} QueryWith(user *gen.T) (gen.T, error) }
如何使用
query.User.QueryWith(&User{Name: "zhangqiang"}) // SELECT * FROM users WHERE username="zhangqiang"
where
where 表达式使您可以更轻松地为 SQL 查询编写 WHERE 子句,让我们以一个简单的例子为例
type Querier interface { // SELECT * FROM @@table // {{where}} // id=@id // {{end}} Query(id int) gen.T }
使用生成的代码,您可以像这样使用它
query.User.Query(10) // SELECT * FROM users WHERE id=10
这是一个更复杂的例子,在这个例子中,您将了解到只有在任何子表达式匹配时才会插入 WHERE 子句,并且它可以智能地修剪 where 子句中不必要的 and、or、xor、,。
type Querier interface { // SELECT * FROM @@table // {{where}} // {{if !start.IsZero()}} // created_time > @start // {{end}} // {{if !end.IsZero()}} // AND created_time < @end // {{end}} // {{end}} FilterWithTime(start, end time.Time) ([]gen.T, error) }
生成的代码可以像这样使用
var ( since = time.Date(2022, 10, 1, 0, 0, 0, 0, time.UTC) end = time.Date(2022, 10, 10, 0, 0, 0, 0, time.UTC) zero = time.Time{} )
query.User.FilterWithTime(since, end) // SELECT * FROM `users` WHERE created_time > "2022-10-01" AND created_time < "2022-10-10"
query.User.FilterWithTime(since, zero) // SELECT * FROM `users` WHERE created_time > "2022-10-01"
query.User.FilterWithTime(zero, end) // SELECT * FROM `users` WHERE created_time < "2022-10-10"
query.User.FilterWithTime(zero, zero) // SELECT * FROM `users`
query.User.Update(User{Name: "jinzhu", Age: 18}, 10) // UPDATE users SET username="jinzhu", age=18, is_adult=1 WHERE id=10
query.User.Update(User{Name: "jinzhu", Age: 0}, 10) // UPDATE users SET username="jinzhu", is_adult=0 WHERE id=10
query.User.Update(User{Age: 0}, 10) // UPDATE users SET is_adult=0 WHERE id=10
for
for 表达式迭代切片以生成 SQL,让我们通过示例进行解释
// SELECT * FROM @@table // {{where}} // {{for _,user:=range users}} // {{if user.Name !="" && user.Age >0}} // (username = @user.Name AND age=@user.Age AND role LIKE concat("%",@user.Role,"%")) OR // {{end}} // {{end}} // {{end}} Filter(users []gen.T) ([]gen.T, error)
用法
query.User.Filter([]User{ {Name: "jinzhu", Age: 18, Role: "admin"}, {Name: "zhangqiang", Age: 18, Role: "admin"}, {Name: "modi", Age: 18, Role: "admin"}, {Name: "songyuan", Age: 18, Role: "admin"}, }) // SELECT * FROM users WHERE // (username = "jinzhu" AND age=18 AND role LIKE concat("%","admin","%")) OR // (username = "zhangqiang" AND age=18 AND role LIKE concat("%","admin","%")) // (username = "modi" AND age=18 AND role LIKE concat("%","admin","%")) OR // (username = "songyuan" AND age=18 AND role LIKE concat("%","admin","%"))