gorm package - gorm.io/gorm - Go Packages
gorm.DB
的复用func (db *DB) DB()
会返回一个db
对象,该对象是可以复用的,而一旦查询开始后,接受者的状态会随着查询方法的调用而改变,例如:
tx := db.Table("tbl_name")
// &tx != &db,db状态没变,可以用db创建其他SQL
anotherTx := tx.Select("field")
// &anotherTx == &tx,tx状态改变了(添加了select条件),没办法复用tx创建另一个SQL
如果是手动事务,Begin()
返回的DB对象是可以复用的:
tx := db.Begin() // 开启事务
fstTx := tx.Table("tbl_1") // &fstTx != &tx
secTx := tx.Table("tbl_2") // &secTx != &tx != &fstTx
fstTx = fstTx.Create("...") // fstTx 状态改变
...
tx.Commit() // 提交fstTx和secTx进行的SQL
GORM 中包含三种方法:链式方法,终结方法以及新会话方法。
链式方法 Chain Method 返回的gorm.DB
对象不可重用,例如:Where(),Select(),Raw(),Joins()
等等,因为它们会将新添加的SQL语句注册到调用它们的DB对象之中,返回的也是该DB对象。
终结方法 Finisher Method 例如Find(),Rows(),First()
会实际执行SQL命令查询数据库。它返回的DB对象同样不可重用。
而新会话方法 New Session Method 返回的DB对象可以重用,例如:Session(),WithContext(),Debug()
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
// 'db' is a newly initialized *gorm.DB, 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` methods return a `*gorm.DB` instance marked as safe for reuse.
// They base a newly initialized `*gorm.Statement` on the 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;