教程 > gorm 教程 > 阅读:171

gorm 链式操作——迹忆客-ag捕鱼王app官网

gorm 允许进行链式操作,所以我们可以像这样写代码

db.where("name = ?", "jinzhu").where("age = ?", 18).first(&user)

gorm 中有三种类型的方法: 链式方法终结方法新建会话方法

链式方法 , 终结方法 之后, gorm 返回一个初始化的 *gorm.db 实例,实例不能安全地重复使用,并且新生成的 sql 可能会被先前的条件污染,例如:

querydb := db.where("name = ?", "jinzhu")
querydb.where("age > ?", 10).first(&user)
// select * from users where name = "jinzhu" and age > 10
querydb.where("age > ?", 20).first(&user2)
// select * from users where name = "jinzhu" and age > 10 and age > 20

为了重新使用初始化的 *gorm.db 实例, 我们可以使用 新建会话方法 创建一个可共享的 *gorm.db, 例如:

querydb := db.where("name = ?", "jinzhu").session(&gorm.session{})
querydb.where("age > ?", 10).first(&user)
// select * from users where name = "jinzhu" and age > 10
querydb.where("age > ?", 20).first(&user2)
// select * from users where name = "jinzhu" and age > 20

链式方法

链式方法是将 clauses 修改或添加到当前 statement 的方法,例如:

where, select, omit, joins, scopes, preload, raw (raw can’t be used with other chainable methods to build sql)…

这是 ,也可以查看 sql 构建器 获取更多关于 clauses 的信息


终结方法

终结(方法) 是会立即执行注册回调的方法,然后生成并执行 sql,比如这些方法:

  • create
  • first
  • find
  • take
  • save
  • update
  • delete
  • scan
  • row
  • rows ...

新建会话方法

gorm 定义了 sessionwithcontextdebug 方法做为 新建会话方法,查看会话 获取详情.

链式方法, finisher 方法之后, gorm 返回一个初始化的 *gorm.db 实例,不能安全地再使用。我们应该使用 新建会话方法 来标记 *gorm.db 为可共享。

让我们用实例来解释它:

示例 1:

db, err := gorm.open(sqlite.open("test.db"), &gorm.config{})
// db is a new initialized `*gorm.db`, which is safe to reuse
db.where("name = ?", "jinzhu").where("age = ?", 18).find(&users)
// `where("name = ?", "jinzhu")` is the first chain method call, it will create an initialized `*gorm.db` instance, aka `*gorm.statement`
// `where("age = ?", 18)` is the second chain method call, it reuses the above `*gorm.statement`, adds new condition `age = 18` to it
// `find(&users)` is a finisher method, it executes registered query callbacks, which generates and runs the following sql:
// select * from users where name = 'jinzhu' and age = 18;
db.where("name = ?", "jinzhu2").where("age = ?", 20).find(&users)
// `where("name = ?", "jinzhu2")` is also the first chain method call, it creates a new `*gorm.statement`
// `where("age = ?", 20)` reuses the above `statement`, and add conditions to it
// `find(&users)` is a finisher method, it executes registered query callbacks, generates and runs the following sql:
// select * from users where name = 'jinzhu2' and age = 20;
db.find(&users)
// `find(&users)` is a finisher method call, it also creates a new `statement` and executes registered query callbacks, generates and runs the following sql:
// select * from users;

(错误的) 示例2:

db, err := gorm.open(sqlite.open("test.db"), &gorm.config{})
// db is a new initialized *gorm.db, which is safe to reuse
tx := db.where("name = ?", "jinzhu")
// `where("name = ?", "jinzhu")` returns an initialized `*gorm.statement` instance after chain method `where`, which is not safe to reuse
// good case
tx.where("age = ?", 18).find(&users)
// `tx.where("age = ?", 18)` use the above `*gorm.statement`, adds new condition to it
// `find(&users)` is a finisher method call, it executes registered query callbacks, generates and runs the following sql:
// select * from users where name = 'jinzhu' and age = 18
// bad case
tx.where("age = ?", 28).find(&users)
// `tx.where("age = ?", 18)` also use the above `*gorm.statement`, and keep adding conditions to it
// so the following generated sql is polluted by the previous conditions:
// select * from users where name = 'jinzhu' and age = 18 and age = 28;

示例 3:

db, err := gorm.open(sqlite.open("test.db"), &gorm.config{})
// db is a new initialized *gorm.db, which is safe to reuse
tx := db.where("name = ?", "jinzhu").session(&gorm.session{})
tx := db.where("name = ?", "jinzhu").withcontext(context.background())
tx := db.where("name = ?", "jinzhu").debug()
// `session`, `withcontext`, `debug` returns `*gorm.db` marked as safe to reuse, newly initialized `*gorm.statement` based on it keeps current conditions
// good case
tx.where("age = ?", 18).find(&users)
// select * from users where name = 'jinzhu' and age = 18
// good case
tx.where("age = ?", 28).find(&users)
// select * from users where name = 'jinzhu' and age = 28;

查看笔记

扫码一下
查看教程更方便
网站地图