sqlboiler
2024-07-09 18:34:12 0 举报
AI智能生成
内部使用
作者其他创作
大纲/内容
sqlboiler
go install github.com/volatiletech/sqlboiler/v4@latest
go install github.com/volatiletech/sqlboiler/v4/drivers/sqlboiler-mysql@latest
go install github.com/volatiletech/sqlboiler/v4/drivers/sqlboiler-mysql@latest
牢牢记住,这是v4
依赖:
go get github.com/volatiletech/sqlboiler/v4
go get github.com/volatiletech/null/v8
sqlboiler mysql --config xx.toml//运行
go get github.com/volatiletech/sqlboiler/v4
go get github.com/volatiletech/null/v8
sqlboiler mysql --config xx.toml//运行
配置文件:
wipe = true # 先删除之前自动生成的文件再重新生成
no-tests = true # 不生成测试代码
add-global-variants = true # 生成使用全局数据源的方法,也就是带 G 后缀的方法
add-panic-variants = true # 生成使用当 error 不为 nil 时 panic 的方法,也就是带 P 后缀的方法
no-context = true # 不需要上下文参数
[mysql]
dbname = "dbname"
host = "127.0.0.1"
user = "root"
pass = "longque55"
sslmode = "false"
wipe = true # 先删除之前自动生成的文件再重新生成
no-tests = true # 不生成测试代码
add-global-variants = true # 生成使用全局数据源的方法,也就是带 G 后缀的方法
add-panic-variants = true # 生成使用当 error 不为 nil 时 panic 的方法,也就是带 P 后缀的方法
no-context = true # 不需要上下文参数
[mysql]
dbname = "dbname"
host = "127.0.0.1"
user = "root"
pass = "longque55"
sslmode = "false"
注意事项:
[psql]
# Removes migrations table, the name column from the addresses table, and
# secret_col of any table from being generated. Foreign keys that reference tables
# or columns that are no longer generated because of whitelists or blacklists may
# cause problems.
blacklist = ["migrations", "addresses.name", "*.secret_col"]
[psql]
# Removes migrations table, the name column from the addresses table, and
# secret_col of any table from being generated. Foreign keys that reference tables
# or columns that are no longer generated because of whitelists or blacklists may
# cause problems.
blacklist = ["migrations", "addresses.name", "*.secret_col"]
这个讨厌的bug,解决方案:
found key user in config, but it was not a string (<nil>)
Error: unable to initialize tables: unable to fetch table data: driver (D:\GOPATH\bin\sqlboiler-mysql.exe) exited non-zero: exit status 1
found key user in config, but it was not a string (<nil>)
Error: unable to initialize tables: unable to fetch table data: driver (D:\GOPATH\bin\sqlboiler-mysql.exe) exited non-zero: exit status 1
go版本:1.19(使用gvm管理go版本)
mysql版本:8.0
需要使用root账户创建一个新的user:我这里叫david1
创建一个数据库,最好不要有_ 我的叫sqlboilerTest
表名和列名必须使用蛇形命名 snake_case。
不要修改任何生成文件,否则会导致重新生成代码出错。
创建一个表,最好老老实实的,不要整骚操作:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
birthdate DATE,
is_active BOOLEAN DEFAULT TRUE
);
mysql版本:8.0
需要使用root账户创建一个新的user:我这里叫david1
创建一个数据库,最好不要有_ 我的叫sqlboilerTest
表名和列名必须使用蛇形命名 snake_case。
不要修改任何生成文件,否则会导致重新生成代码出错。
创建一个表,最好老老实实的,不要整骚操作:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
birthdate DATE,
is_active BOOLEAN DEFAULT TRUE
);
wipe = true # 先删除之前自动生成的文件再重新生成
no-tests = true # 不生成测试代码
add-global-variants = true # 生成使用全局数据源的方法,也就是带 G 后缀的方法
add-panic-variants = true # 生成使用当 error 不为 nil 时 panic 的方法,也就是带 P 后缀的方>法
no-context = true # 不需要上下文参数
[mysql]
dbname = "sqlboilerTest"
host = "localhost"
user = "david1"
pass = "123456"
sslmode = "false"
no-tests = true # 不生成测试代码
add-global-variants = true # 生成使用全局数据源的方法,也就是带 G 后缀的方法
add-panic-variants = true # 生成使用当 error 不为 nil 时 panic 的方法,也就是带 P 后缀的方>法
no-context = true # 不需要上下文参数
[mysql]
dbname = "sqlboilerTest"
host = "localhost"
user = "david1"
pass = "123456"
sslmode = "false"
生成好了之后,首先设置数据源:
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/volatiletech/sqlboiler/v4/boil"
"github.com/volatiletech/sqlboiler/v4/queries/qm"
"log"
"sqlboiler_test/models"
)
func main() {
// 创建数据源
db, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/tbname?parseTime=True")
if err != nil {
log.Fatal(err)
}
// 设置全局数据源
boil.SetDB(db)
}
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/volatiletech/sqlboiler/v4/boil"
"github.com/volatiletech/sqlboiler/v4/queries/qm"
"log"
"sqlboiler_test/models"
)
func main() {
// 创建数据源
db, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/tbname?parseTime=True")
if err != nil {
log.Fatal(err)
}
// 设置全局数据源
boil.SetDB(db)
}
增:
func InsertUserDemo() {
user := models.User{
Username: "david2",
Password: "123456",
NickName: "dashabi",
}
user.InsertGP(boil.Infer())
fmt.Printf("%+v", user)
}
func InsertUserDemo() {
user := models.User{
Username: "david2",
Password: "123456",
NickName: "dashabi",
}
user.InsertGP(boil.Infer())
fmt.Printf("%+v", user)
}
删:
func DeleteUserDemo() {
// 根据 User.ID 进行删除
user := models.User{ID: 1}
count := user.DeleteGP()
fmt.Println(count)
// 根据 UserSlice 批量删除
users := models.Users().AllGP()
count = users.DeleteAllGP()
fmt.Println(count)
// 根据条件进行删除
count, _ = models.Users(models.UserWhere.Username.EQ("username1")).DeleteAllG()
fmt.Println(count)
}
func DeleteUserDemo() {
// 根据 User.ID 进行删除
user := models.User{ID: 1}
count := user.DeleteGP()
fmt.Println(count)
// 根据 UserSlice 批量删除
users := models.Users().AllGP()
count = users.DeleteAllGP()
fmt.Println(count)
// 根据条件进行删除
count, _ = models.Users(models.UserWhere.Username.EQ("username1")).DeleteAllG()
fmt.Println(count)
}
查:
func SelectUserDemo() {
// 根据条件查询(如果不指定条件则查询全部)
users := models.Users(qm.Select(models.UserColumns.ID, models.UserColumns.NickName),
models.UserWhere.Username.EQ("username1")).AllGP()
fmt.Println(users)
// 查询数量
count := models.Users(models.UserWhere.Username.EQ("username1")).CountGP()
fmt.Println(count)
// 根据主键查询
user, err := models.FindUserG(1)
if err == sql.ErrNoRows {
// 业务处理
}
fmt.Println(user)
}
func SelectUserDemo() {
// 根据条件查询(如果不指定条件则查询全部)
users := models.Users(qm.Select(models.UserColumns.ID, models.UserColumns.NickName),
models.UserWhere.Username.EQ("username1")).AllGP()
fmt.Println(users)
// 查询数量
count := models.Users(models.UserWhere.Username.EQ("username1")).CountGP()
fmt.Println(count)
// 根据主键查询
user, err := models.FindUserG(1)
if err == sql.ErrNoRows {
// 业务处理
}
fmt.Println(user)
}
改:
func UpdateUserDemo() {
// 根据 User.ID 进行更新
user := models.User{ID: 1, NickName: "nickName1001"}
count := user.UpdateGP(boil.Whitelist(models.UserColumns.NickName))
fmt.Println(count)
// 根据 UserSlice 批量更新
users := models.Users().AllGP()
count = users.UpdateAllGP(models.M{models.UserColumns.NickName: "updateAllNickName"})
fmt.Println(count)
// 根据条件进行更新
count, _ = models.Users(models.UserWhere.NickName.EQ("updateAllNickName")).
UpdateAllG(models.M{models.UserColumns.NickName: "updateAllNickName2"})
fmt.Println(count)
}
func UpdateUserDemo() {
// 根据 User.ID 进行更新
user := models.User{ID: 1, NickName: "nickName1001"}
count := user.UpdateGP(boil.Whitelist(models.UserColumns.NickName))
fmt.Println(count)
// 根据 UserSlice 批量更新
users := models.Users().AllGP()
count = users.UpdateAllGP(models.M{models.UserColumns.NickName: "updateAllNickName"})
fmt.Println(count)
// 根据条件进行更新
count, _ = models.Users(models.UserWhere.NickName.EQ("updateAllNickName")).
UpdateAllG(models.M{models.UserColumns.NickName: "updateAllNickName2"})
fmt.Println(count)
}
官网配置例子:
output = "my_models"
wipe = true
no-tests = true
[psql]
dbname = "dbname"
host = "localhost"
port = 5432
user = "dbusername"
pass = "dbpassword"
schema = "myschema"
blacklist = ["migrations", "other"]
[mysql]
dbname = "dbname"
host = "localhost"
port = 3306
user = "dbusername"
pass = "dbpassword"
sslmode = "false"
[mssql]
dbname = "dbname"
host = "localhost"
port = 1433
user = "dbusername"
pass = "dbpassword"
sslmode = "disable"
schema = "notdbo"
output = "my_models"
wipe = true
no-tests = true
[psql]
dbname = "dbname"
host = "localhost"
port = 5432
user = "dbusername"
pass = "dbpassword"
schema = "myschema"
blacklist = ["migrations", "other"]
[mysql]
dbname = "dbname"
host = "localhost"
port = 3306
user = "dbusername"
pass = "dbpassword"
sslmode = "false"
[mssql]
dbname = "dbname"
host = "localhost"
port = 1433
user = "dbusername"
pass = "dbpassword"
sslmode = "disable"
schema = "notdbo"
sqlboiler会自动生成名字,但如果你的数据库名字起的不好且无法修改,或者 sqlboiler 无法推断你的名字,
那么你可以使用 别名 去修改生成代码中的表名、列名:
# 为原始表名为 user 的表设置别名
[aliases.tables.user]
# 大写复数时的名字
up_plural = "UserInfos"
# 大写单数时的名字
up_singular = "UserInfo"
# 小写复数时的名字
down_plural = "userInfos"
# 小写单数时的名字
down_singular = "userInfo"
# 为表user的password列设置别名 psw
[aliases.tables.user.columns]
password = "psw"
那么你可以使用 别名 去修改生成代码中的表名、列名:
# 为原始表名为 user 的表设置别名
[aliases.tables.user]
# 大写复数时的名字
up_plural = "UserInfos"
# 大写单数时的名字
up_singular = "UserInfo"
# 小写复数时的名字
down_plural = "userInfos"
# 小写单数时的名字
down_singular = "userInfo"
# 为表user的password列设置别名 psw
[aliases.tables.user.columns]
password = "psw"
注意事项(官方版):
在生成代码时忘记排除你不想要的表,比如迁移表。
表忘记设置主键,所有表都需要主键。
兼容性测试需要权限去创建一个数据库进行测试,请确保在 sqlboiler.toml 中配置足够的权限。
nil或者被关闭的数据源(database handle)。确保你传入的 boil.Executor 不为 nil,也就是 boil.SetDB(db) 的 db。
如果你使用 G (全部数据源),请确保已经初始化全局数据源并使用boil.SetDB()
命名冲突 Naming collisions,如果存在命名冲突而编译失败,请查看别名特性。
字段没有被插入(通常是默认值为true的布尔类型),boil.Infer把Go的所有零值都当成你不想插入。当你想插入bool类型的false时,请使用 whitelist/greylist 让sqlboiler知道你想插入什么字段。
decimal 库错误,比如 pq: encode: unknown type types.NullDecimal 是因为 github.com/ericlargergren/decimal 库太新或者损坏导致,请在go.mod中使用下面版本 github.com/ericlagergren/decimal v0.0.0-20181231230500-73749d4874d5
其他的错误原因可以通过查看生成的代码,或者设置 boil.DebugMode 为true 可以查看 sql和参数。也可以设置 boil.DebugWriter 重定向 debug 输出流,默认是 os.Stdout。
在生成代码时忘记排除你不想要的表,比如迁移表。
表忘记设置主键,所有表都需要主键。
兼容性测试需要权限去创建一个数据库进行测试,请确保在 sqlboiler.toml 中配置足够的权限。
nil或者被关闭的数据源(database handle)。确保你传入的 boil.Executor 不为 nil,也就是 boil.SetDB(db) 的 db。
如果你使用 G (全部数据源),请确保已经初始化全局数据源并使用boil.SetDB()
命名冲突 Naming collisions,如果存在命名冲突而编译失败,请查看别名特性。
字段没有被插入(通常是默认值为true的布尔类型),boil.Infer把Go的所有零值都当成你不想插入。当你想插入bool类型的false时,请使用 whitelist/greylist 让sqlboiler知道你想插入什么字段。
decimal 库错误,比如 pq: encode: unknown type types.NullDecimal 是因为 github.com/ericlargergren/decimal 库太新或者损坏导致,请在go.mod中使用下面版本 github.com/ericlagergren/decimal v0.0.0-20181231230500-73749d4874d5
其他的错误原因可以通过查看生成的代码,或者设置 boil.DebugMode 为true 可以查看 sql和参数。也可以设置 boil.DebugWriter 重定向 debug 输出流,默认是 os.Stdout。
官方示例:
CREATE TABLE pilots (
id integer NOT NULL,
name text NOT NULL
);
ALTER TABLE pilots ADD CONSTRAINT pilot_pkey PRIMARY KEY (id);
CREATE TABLE jets (
id integer NOT NULL,
pilot_id integer NOT NULL,
age integer NOT NULL,
name text NOT NULL,
color text NOT NULL
);
ALTER TABLE jets ADD CONSTRAINT jet_pkey PRIMARY KEY (id);
CREATE TABLE languages (
id integer NOT NULL,
language text NOT NULL
);
ALTER TABLE languages ADD CONSTRAINT language_pkey PRIMARY KEY (id);
CREATE TABLE pilot_languages (
pilot_id integer NOT NULL,
language_id integer NOT NULL
);
ALTER TABLE pilot_languages ADD CONSTRAINT pilot_language_pkey PRIMARY KEY (pilot_id, language_id);
CREATE TABLE pilots (
id integer NOT NULL,
name text NOT NULL
);
ALTER TABLE pilots ADD CONSTRAINT pilot_pkey PRIMARY KEY (id);
CREATE TABLE jets (
id integer NOT NULL,
pilot_id integer NOT NULL,
age integer NOT NULL,
name text NOT NULL,
color text NOT NULL
);
ALTER TABLE jets ADD CONSTRAINT jet_pkey PRIMARY KEY (id);
CREATE TABLE languages (
id integer NOT NULL,
language text NOT NULL
);
ALTER TABLE languages ADD CONSTRAINT language_pkey PRIMARY KEY (id);
CREATE TABLE pilot_languages (
pilot_id integer NOT NULL,
language_id integer NOT NULL
);
ALTER TABLE pilot_languages ADD CONSTRAINT pilot_language_pkey PRIMARY KEY (pilot_id, language_id);
自动 CreatedAt/UpdatedAt:
如果你生成的 SQLBoiler models
包含 created_at 或 updated_at
列将会被自动设置为 time.Now()
可以通过 boil.SetLocation()设置时区。
如果你生成的 SQLBoiler models
包含 created_at 或 updated_at
列将会被自动设置为 time.Now()
可以通过 boil.SetLocation()设置时区。
查询构造器:
启动方法被于构造查询模块系统(Query Mod System)。
启动方法使用一组 查询模块(Query Mod) 作为参数,
并在最后调用一个结束方法(Finisher Method)
启动方法被于构造查询模块系统(Query Mod System)。
启动方法使用一组 查询模块(Query Mod) 作为参数,
并在最后调用一个结束方法(Finisher Method)
// SELECT COUNT(*) FROM user;
count, err := models.Users().Count(ctx, db)
// SELECT * FROM user LIMIT 5;
users, err := models.Users(qm.Limit(5)).All(ctx, db)
// DELETE FROM user WHERE id = 1;
err := models.Users(qm.Where("id = ?", 1)).DeleteAll(ctx, db)
// 下面是类型安全的方式
err := models.Users(models.UserWhere.ID.EQ(1)).DeleteAll(ctx, db)
//需要直接指定数据表,也可以使用models.NewQuery():
rows, err := models.NewQuery(qm.From("user")).Query(db)
count, err := models.Users().Count(ctx, db)
// SELECT * FROM user LIMIT 5;
users, err := models.Users(qm.Limit(5)).All(ctx, db)
// DELETE FROM user WHERE id = 1;
err := models.Users(qm.Where("id = ?", 1)).DeleteAll(ctx, db)
// 下面是类型安全的方式
err := models.Users(models.UserWhere.ID.EQ(1)).DeleteAll(ctx, db)
//需要直接指定数据表,也可以使用models.NewQuery():
rows, err := models.NewQuery(qm.From("user")).Query(db)
查询模块系统(Query Mod System):SQLBoiler为表、列生成了类型安全的标识符。使用这些标识符将更加安全,因为如果数据库进行修改之后会产生编译错误而不是运行时错误。
// 点 import 让我们可以直接使用里面的函数而不需要加 "qm." 前缀
import . "github.com/volatiletech/sqlboiler/v4/queries/qm"
// 对生成的 model 使用 raw query(原始查询)
// 如果这个查询模块存在,其他查询模块将被覆盖
SQL("select * from pilots where id=?", 10)
models.Pilots(SQL("select * from pilots where id=?", 10)).All()
Select("id", "name") // 指定查询列
Select(models.PilotColumns.ID, models.PilotColumns.Name)
From("pilots as p") // 指定from表
From(models.TableNames.Pilots + " as p")
// WHERE 语句构建
Where("name=?", "John")
models.PilotWhere.Name.EQ("John")
And("age=?", 24)
// 目前还没有等价的类型安全查询
Or("height=?", 183)
// 目前还没有等价的类型安全查询
Where("(name=? and age=?) or (age=?)", "John", 5, 6)
// Expr 允许手动把语句弄成一组
Where(
Expr(
models.PilotWhere.Name.EQ("John"),
Or2(models.PilotWhere.Age.EQ(5)),
),
Or2(models.PilotAge),
)
// WHERE IN 语句构建
WhereIn("name, age in ?", "John", 24, "Tim", 33) // 生成: WHERE ("name","age") IN (($1,$2),($3,$4))
WhereIn(fmt.Sprintf("%s, %s in ?", models.PilotColumns.Name, models.PilotColumns.Age, "John", 24, "Tim", 33))
AndIn("weight in ?", 84)
AndIn(models.PilotColumns.Weight + " in ?", 84)
OrIn("height in ?", 183, 177, 204)
OrIn(models.PilotColumns.Height + " in ?", 183, 177, 204)
InnerJoin("pilots p on jets.pilot_id=?", 10)
InnerJoin(models.TableNames.Pilots + " p on " + models.TableNames.Jets + "." + models.JetColumns.PilotID + "=?", 10)
GroupBy("name")
GroupBy("name like ? DESC, name", "John")
GroupBy(models.PilotColumns.Name)
OrderBy("age, height")
OrderBy(models.PilotColumns.Age, models.PilotColumns.Height)
Having("count(jets) > 2")
Having(fmt.Sprintf("count(%s) > 2", models.TableNames.Jets)
Limit(15)
Offset(5)
// 显式锁定
For("update")
// With 语句
With("cte_0 AS (SELECT * FROM table_0 WHERE thing=? AND stuff=?)")
// 点 import 让我们可以直接使用里面的函数而不需要加 "qm." 前缀
import . "github.com/volatiletech/sqlboiler/v4/queries/qm"
// 对生成的 model 使用 raw query(原始查询)
// 如果这个查询模块存在,其他查询模块将被覆盖
SQL("select * from pilots where id=?", 10)
models.Pilots(SQL("select * from pilots where id=?", 10)).All()
Select("id", "name") // 指定查询列
Select(models.PilotColumns.ID, models.PilotColumns.Name)
From("pilots as p") // 指定from表
From(models.TableNames.Pilots + " as p")
// WHERE 语句构建
Where("name=?", "John")
models.PilotWhere.Name.EQ("John")
And("age=?", 24)
// 目前还没有等价的类型安全查询
Or("height=?", 183)
// 目前还没有等价的类型安全查询
Where("(name=? and age=?) or (age=?)", "John", 5, 6)
// Expr 允许手动把语句弄成一组
Where(
Expr(
models.PilotWhere.Name.EQ("John"),
Or2(models.PilotWhere.Age.EQ(5)),
),
Or2(models.PilotAge),
)
// WHERE IN 语句构建
WhereIn("name, age in ?", "John", 24, "Tim", 33) // 生成: WHERE ("name","age") IN (($1,$2),($3,$4))
WhereIn(fmt.Sprintf("%s, %s in ?", models.PilotColumns.Name, models.PilotColumns.Age, "John", 24, "Tim", 33))
AndIn("weight in ?", 84)
AndIn(models.PilotColumns.Weight + " in ?", 84)
OrIn("height in ?", 183, 177, 204)
OrIn(models.PilotColumns.Height + " in ?", 183, 177, 204)
InnerJoin("pilots p on jets.pilot_id=?", 10)
InnerJoin(models.TableNames.Pilots + " p on " + models.TableNames.Jets + "." + models.JetColumns.PilotID + "=?", 10)
GroupBy("name")
GroupBy("name like ? DESC, name", "John")
GroupBy(models.PilotColumns.Name)
OrderBy("age, height")
OrderBy(models.PilotColumns.Age, models.PilotColumns.Height)
Having("count(jets) > 2")
Having(fmt.Sprintf("count(%s) > 2", models.TableNames.Jets)
Limit(15)
Offset(5)
// 显式锁定
For("update")
// With 语句
With("cte_0 AS (SELECT * FROM table_0 WHERE thing=? AND stuff=?)")
原始查询:
err := queries.Raw("select * from pilots where id=?", 5).Bind(ctx, db, &obj)
可以使用自己的struct或生成的struct去``Bind() 。Bind()`支持绑定到单独一个对象或者一个slice。
queries.Raw() 也有一个不需要执行对象绑定的方法。
也可以使用 models.NewQuery() 去应用 查询模块系统 结合自定义的 struct。
err := queries.Raw("select * from pilots where id=?", 5).Bind(ctx, db, &obj)
可以使用自己的struct或生成的struct去``Bind() 。Bind()`支持绑定到单独一个对象或者一个slice。
queries.Raw() 也有一个不需要执行对象绑定的方法。
也可以使用 models.NewQuery() 去应用 查询模块系统 结合自定义的 struct。
bind():
Bind()结束函数允许你通过原始查询或者
查询构造方式去绑定你自定义的struct或生成的struct。
Bind()结束函数允许你通过原始查询或者
查询构造方式去绑定你自定义的struct或生成的struct。
// 自定义 struct 使用两个生成的 structs
type PilotAndJet struct {
models.Pilot `boil:",bind"`
models.Jet `boil:",bind"`
}
var paj PilotAndJet
// 使用原始查询
err := queries.Raw(db, `
select pilots.id as "pilots.id", pilots.name as "pilots.name",
jets.id as "jets.id", jets.pilot_id as "jets.pilot_id",
jets.age as "jets.age", jets.name as "jets.name", jets.color as "jets.color"
from pilots inner join jets on jets.pilot_id=?`, 23,
).Bind(&paj)
// 使用查询构造
err := models.NewQuery(
Select("pilots.id", "pilots.name", "jets.id", "jets.pilot_id", "jets.age", "jets.name", "jets.color"),
From("pilots"),
InnerJoin("jets on jets.pilot_id = pilots.id"),
).Bind(ctx, db, &paj)
type PilotAndJet struct {
models.Pilot `boil:",bind"`
models.Jet `boil:",bind"`
}
var paj PilotAndJet
// 使用原始查询
err := queries.Raw(db, `
select pilots.id as "pilots.id", pilots.name as "pilots.name",
jets.id as "jets.id", jets.pilot_id as "jets.pilot_id",
jets.age as "jets.age", jets.name as "jets.name", jets.color as "jets.color"
from pilots inner join jets on jets.pilot_id=?`, 23,
).Bind(&paj)
// 使用查询构造
err := models.NewQuery(
Select("pilots.id", "pilots.name", "jets.id", "jets.pilot_id", "jets.age", "jets.name", "jets.color"),
From("pilots"),
InnerJoin("jets on jets.pilot_id = pilots.id"),
).Bind(ctx, db, &paj)
对Bind()的控制可以使用下面的struct tag 模式:
type CoolObject struct {
// 如果没有指定名字,会使用列名的 TitleCase 进行匹配
Frog int
// 如果指定名字,会使用列名的 titlecased 进行匹配
Specify an alternative name for the column, it will
// be titlecased for matching, can be whatever you like.
Cat int `boil:"kitten"`
// 忽略这个域,不绑定
Pig int `boil:"-"`
// 不是用正常的方式进行绑定,像 sql-able strict 如 time.Time
// 递归的搜索Dog struct 中的查询结果名
Dog `boil:",bind"`
// 同上,除了指定一个不同的表名
Mouse `boil:"rodent,bind"`
// 忽略这个域,不绑定
Bird `boil:"-"`
}
// 如果没有指定名字,会使用列名的 TitleCase 进行匹配
Frog int
// 如果指定名字,会使用列名的 titlecased 进行匹配
Specify an alternative name for the column, it will
// be titlecased for matching, can be whatever you like.
Cat int `boil:"kitten"`
// 忽略这个域,不绑定
Pig int `boil:"-"`
// 不是用正常的方式进行绑定,像 sql-able strict 如 time.Time
// 递归的搜索Dog struct 中的查询结果名
Dog `boil:",bind"`
// 同上,除了指定一个不同的表名
Mouse `boil:"rodent,bind"`
// 忽略这个域,不绑定
Bird `boil:"-"`
}
事务:(也可以使用 boil.BeginTx() 通过全局数据源开启一个事务,
它利用 boil.SetDB() 设置的数据源。)
tx, err := db.BeginTx(ctx, nil)
if err != nil {
return err
}
users, _ := models.Pilots().All(ctx, tx)
users.DeleteAll(ctx, tx)
// Rollback 或 commit
tx.Commit()
tx.Rollback()
它利用 boil.SetDB() 设置的数据源。)
tx, err := db.BeginTx(ctx, nil)
if err != nil {
return err
}
users, _ := models.Pilots().All(ctx, tx)
users.DeleteAll(ctx, tx)
// Rollback 或 commit
tx.Commit()
tx.Rollback()
debug日志:
boil.DebugMode = true
// 可以选择设置输出源. 默认是 os.Stdout
fh, _ := os.Open("debug.txt")
boil.DebugWriter = fh
boil.DebugMode = true
// 可以选择设置输出源. 默认是 os.Stdout
fh, _ := os.Open("debug.txt")
boil.DebugWriter = fh
// 自定义 struct 去查询一个子集
type JetInfo struct {
AgeSum int `boil:"age_sum"`
Count int `boil:"juicy_count"`
}
var info JetInfo
// 使用查询构造
err := models.NewQuery(Select("sum(age) as age_sum", "count(*) as juicy_count", From("jets"))).Bind(ctx, db, &info)
// 使用原始查询
err := queries.Raw(`select sum(age) as "age_sum", count(*) as "juicy_count" from jets`).Bind(ctx, db, &info)
type JetInfo struct {
AgeSum int `boil:"age_sum"`
Count int `boil:"juicy_count"`
}
var info JetInfo
// 使用查询构造
err := models.NewQuery(Select("sum(age) as age_sum", "count(*) as juicy_count", From("jets"))).Bind(ctx, db, &info)
// 使用原始查询
err := queries.Raw(`select sum(age) as "age_sum", count(*) as "juicy_count" from jets`).Bind(ctx, db, &info)
函数变体:
函数可以生成它的变体通过 --add-global-variants 和 --add-panic-variants
函数可以生成它的变体通过 --add-global-variants 和 --add-panic-variants
// 设置全局数据库把柄(数据源)G方法变体
boil.SetDB(db)
pilot, _ := models.FindPilot(ctx, db, 1)
err := pilot.Delete(ctx, db) // 普通模式需要db参数
pilot.DeleteP(ctx, db) // P变体,需要db参数并在error时panic
err := pilot.DeleteG(ctx) // G变体,不需要db参数
pilot.DeleteGP(ctx) // GP变体,不需要db参数并在error时panic
db.Begin() // 正常的方式创建一个事务
boil.BeginTx(ctx, nil) // 使用全局数据源创建事务
boil.SetDB(db)
pilot, _ := models.FindPilot(ctx, db, 1)
err := pilot.Delete(ctx, db) // 普通模式需要db参数
pilot.DeleteP(ctx, db) // P变体,需要db参数并在error时panic
err := pilot.DeleteG(ctx) // G变体,不需要db参数
pilot.DeleteGP(ctx) // GP变体,不需要db参数并在error时panic
db.Begin() // 正常的方式创建一个事务
boil.BeginTx(ctx, nil) // 使用全局数据源创建事务
结束方法:
// 调用方式和下面类似:
models.Pilots().All(ctx, db)
One() // 查询一行 (与LIMIT(1)相同)
All() // 查询全部 (与SELECT * FROM相同)
Count() // 查询行数 (与COUNT(*)相同)
UpdateAll(models.M{"name": "John", "age": 23}) // 更新所有匹配行
DeleteAll() // 删除所有匹配行
Exists() // 返回一个bool表示所查询的行是否存在
Bind(&myObj) // 绑定查询结构到你自己的struct
Exec() // 执行不需要任何返回的SQL查询
QueryRow() // 执行需要一行返回的SQL查询
Query() // 执行需要多行返回的SQL查询
// 调用方式和下面类似:
models.Pilots().All(ctx, db)
One() // 查询一行 (与LIMIT(1)相同)
All() // 查询全部 (与SELECT * FROM相同)
Count() // 查询行数 (与COUNT(*)相同)
UpdateAll(models.M{"name": "John", "age": 23}) // 更新所有匹配行
DeleteAll() // 删除所有匹配行
Exists() // 返回一个bool表示所查询的行是否存在
Bind(&myObj) // 绑定查询结构到你自己的struct
Exec() // 执行不需要任何返回的SQL查询
QueryRow() // 执行需要一行返回的SQL查询
Query() // 执行需要多行返回的SQL查询
自由主题
win10的bug 找不到user对应的名字,目前没有好的解决方案
(github上出现的类似解决方案都无法解决)
(github上出现的类似解决方案都无法解决)
需要配置哪个数据库都去sqlboiler_example去取
后续有新的需要添加再慢慢扩充
!!!不要改动example!!!(除非官方改动)
后续有新的需要添加再慢慢扩充
!!!不要改动example!!!(除非官方改动)
优点:整体替换而不是寻找文件的不同,便于开发
收藏
0 条评论
下一页
为你推荐
查看更多
抱歉,暂无相关内容