SQL 构建器 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.


本站和网页 https://gorm.io/zh_CN/docs/sql_builder.html 的作者无关,不对其内容负责。快照谨为网络故障时之索引,不代表被搜索网站的即时页面。

SQL 构建器 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.
GORM
文档Gen社区API贡献
简体中文
English
简体中文
Deutsch
Español
bahasa Indonesia
Italiano
日本語
Русский
French
한국어
SQL 构建器
原生 SQL原生查询 SQL 和 Scan
type Result struct { ID int Name string Age int}var result Resultdb.Raw("SELECT id, name, age FROM users WHERE name = ?", 3).Scan(&result)db.Raw("SELECT id, name, age FROM users WHERE name = ?", 3).Scan(&result)var age intdb.Raw("SELECT SUM(age) FROM users WHERE role = ?", "admin").Scan(&age)var users []Userdb.Raw("UPDATE users SET name = ? WHERE age = ? RETURNING id, name", "jinzhu", 20).Scan(&users)
Exec 原生 SQL
db.Exec("DROP TABLE users")db.Exec("UPDATE orders SET shipped_at = ? WHERE id IN ?", time.Now(), []int64{1, 2, 3})// Exec with SQL Expressiondb.Exec("UPDATE users SET money = ? WHERE name = ?", gorm.Expr("money * ? + ?", 10000, 1), "jinzhu")
注意 GORM 允许缓存预编译 SQL 语句来提高性能,查看 性能 获取详情
命名参数GORM 支持 sql.NamedArg、map[string]interface{}{} 或 struct 形式的命名参数,例如:
db.Where("name1 = @name OR name2 = @name", sql.Named("name", "jinzhu")).Find(&user)// SELECT * FROM `users` WHERE name1 = "jinzhu" OR name2 = "jinzhu"db.Where("name1 = @name OR name2 = @name", map[string]interface{}{"name": "jinzhu2"}).First(&result3)// SELECT * FROM `users` WHERE name1 = "jinzhu2" OR name2 = "jinzhu2" ORDER BY `users`.`id` LIMIT 1// 原生 SQL 及命名参数db.Raw("SELECT * FROM users WHERE name1 = @name OR name2 = @name2 OR name3 = @name", sql.Named("name", "jinzhu1"), sql.Named("name2", "jinzhu2")).Find(&user)// SELECT * FROM users WHERE name1 = "jinzhu1" OR name2 = "jinzhu2" OR name3 = "jinzhu1"db.Exec("UPDATE users SET name1 = @name, name2 = @name2, name3 = @name", sql.Named("name", "jinzhunew"), sql.Named("name2", "jinzhunew2"))// UPDATE users SET name1 = "jinzhunew", name2 = "jinzhunew2", name3 = "jinzhunew"db.Raw("SELECT * FROM users WHERE (name1 = @name AND name3 = @name) AND name2 = @name2", map[string]interface{}{"name": "jinzhu", "name2": "jinzhu2"}).Find(&user)// SELECT * FROM users WHERE (name1 = "jinzhu" AND name3 = "jinzhu") AND name2 = "jinzhu2"type NamedArgument struct { Name string Name2 string}db.Raw("SELECT * FROM users WHERE (name1 = @Name AND name3 = @Name) AND name2 = @Name2", NamedArgument{Name: "jinzhu", Name2: "jinzhu2"}).Find(&user)// SELECT * FROM users WHERE (name1 = "jinzhu" AND name3 = "jinzhu") AND name2 = "jinzhu2"
DryRun 模式在不执行的情况下生成 SQL 及其参数,可以用于准备或测试生成的 SQL,详情请参考 Session
stmt := db.Session(&Session{DryRun: true}).First(&user, 1).Statementstmt.SQL.String() //=> SELECT * FROM `users` WHERE `id` = $1 ORDER BY `id`stmt.Vars //=> []interface{}{1}
ToSQL返回生成的 SQL 但不执行。
GORM使用 database/sql 的参数占位符来构建 SQL 语句,它会自动转义参数以避免 SQL 注入,但我们不保证生成 SQL 的安全,请只用于调试。
sql := DB.ToSQL(func(tx *gorm.DB) *gorm.DB { return tx.Model(&User{}).Where("id = ?", 100).Limit(10).Order("age desc").Find(&[]User{})})sql //=> SELECT * FROM "users" WHERE id = 100 AND "users"."deleted_at" IS NULL ORDER BY age desc LIMIT 10
Row & Rows获取 *sql.Row 结果
// 使用 GORM API 构建 SQLrow := db.Table("users").Where("name = ?", "jinzhu").Select("name", "age").Row()row.Scan(&name, &age)// 使用原生 SQLrow := db.Raw("select name, age, email from users where name = ?", "jinzhu").Row()row.Scan(&name, &age, &email)
获取 *sql.Rows 结果
// 使用 GORM API 构建 SQLrows, err := db.Model(&User{}).Where("name = ?", "jinzhu").Select("name, age, email").Rows()defer rows.Close()for rows.Next() { rows.Scan(&name, &age, &email) // 业务逻辑...}// 原生 SQLrows, err := db.Raw("select name, age, email from users where name = ?", "jinzhu").Rows()defer rows.Close()for rows.Next() { rows.Scan(&name, &age, &email) // 业务逻辑...}
转到 FindInBatches 获取如何在批量中查询和处理记录的信息, 转到 Group 条件 获取如何构建复杂 SQL 查询的信息
将 sql.Rows 扫描至 model使用 ScanRows 将一行记录扫描至 struct,例如:
rows, err := db.Model(&User{}).Where("name = ?", "jinzhu").Select("name, age, email").Rows() // (*sql.Rows, error)defer rows.Close()var user Userfor rows.Next() { // ScanRows 将一行扫描至 user db.ScanRows(rows, &user) // 业务逻辑...}
连接在一条 tcp DB 连接中运行多条 SQL (不是事务)
db.Connection(func(tx *gorm.DB) error { tx.Exec("SET my.role = ?", "admin") tx.First(&User{})})
高级子句(Clause)GORM 内部使用 SQL builder 生成 SQL。对于每个操作,GORM 都会创建一个 *gorm.Statement 对象,所有的 GORM API 都是在为 statement 添加、修改 子句,最后,GORM 会根据这些子句生成 SQL
例如,当通过 First 进行查询时,它会在 Statement 中添加以下子句
clause.Select{Columns: "*"}clause.From{Tables: clause.CurrentTable}clause.Limit{Limit: 1}clause.OrderByColumn{ Column: clause.Column{Table: clause.CurrentTable, Name: clause.PrimaryKey},}
然后 GORM 在 Query callback 中构建最终的查询 SQL,像这样:
Statement.Build("SELECT", "FROM", "WHERE", "GROUP BY", "ORDER BY", "LIMIT", "FOR")
生成 SQL:
SELECT * FROM `users` ORDER BY `users`.`id` LIMIT 1
您可以自定义 子句 并与 GORM 一起使用,这需要实现 Interface 接口
可以参考 示例
子句构造器不同的数据库, 子句可能会生成不同的 SQL,例如:
db.Offset(10).Limit(5).Find(&users)// SQL Server 会生成// SELECT * FROM "users" OFFSET 10 ROW FETCH NEXT 5 ROWS ONLY// MySQL 会生成// SELECT * FROM `users` LIMIT 5 OFFSET 10
之所以支持 Clause,是因为 GORM 允许数据库驱动程序通过注册 Clause Builder 来取代默认值,这儿有一个 Limit 的示例
子句选项GORM 定义了很多 子句,其中一些 子句提供了你可能会用到的选项
尽管很少会用到它们,但如果你发现 GORM API 与你的预期不符合。这可能可以很好地检查它们,例如:
db.Clauses(clause.Insert{Modifier: "IGNORE"}).Create(&user)// INSERT IGNORE INTO users (name,age...) VALUES ("jinzhu",18...);
StatementModifierGORM 提供了 StatementModifier 接口,允许您修改语句,使其符合您的要求,这儿有一个 Hint 示例
import "gorm.io/hints"db.Clauses(hints.New("hint")).Find(&User{})// SELECT * /*+ hint */ FROM `users`
最后更新于 2022-12-15
上一个接下来
Platinum Sponsors
Become a Sponsor!
Gold Sponsors
Become a Sponsor!
Platinum Sponsors
Become a Sponsor!
Gold Sponsors
Become a Sponsor!
内容
原生 SQL命名参数DryRun 模式ToSQLRow & Rows将 sql.Rows 扫描至 model连接高级子句(Clause)子句构造器子句选项StatementModifier
改进此页面
回到顶部
入门指南概述声明模型连接到数据库CRUD 接口创建查询高级查询更新删除原生 SQL 和 SQL 生成器关联Belongs ToHas OneHas ManyMany To Many关联模式预加载教程Context错误处理链式操作Session钩子事务迁移Logger通用数据库接口性能自定义数据类型Scope约定设置高级主题Database ResolverShardingSerializerPrometheus提示索引约束复合主键安全GORM 配置编写插件编写驱动更新日志社区贡献翻译当前页面
2013~2022 Jinzhu
Documentation licensed under CC BY 4.0.
感谢 七牛云 对 CDN 的赞助,无闻 对域名 gorm.cn 的捐赠
浙ICP备2020033190号-1
主页
文档Gen社区API贡献
入门指南概述声明模型连接到数据库CRUD 接口创建查询高级查询更新删除原生 SQL 和 SQL 生成器关联Belongs ToHas OneHas ManyMany To Many关联模式预加载教程Context错误处理链式操作Session钩子事务迁移Logger通用数据库接口性能自定义数据类型Scope约定设置高级主题Database ResolverShardingSerializerPrometheus提示索引约束复合主键安全GORM 配置编写插件编写驱动更新日志社区贡献翻译当前页面
简体中文
English
简体中文
Deutsch
Español
bahasa Indonesia
Italiano
日本語
Русский
French
한국어