详解gorm中DB对象的clone属性

详解gorm中DB对象的clone属性

Gorm 版本:v1.22.4

Where函数源码

// Where add conditions
func (db *DB) Where(query interface{}, args ...interface{}) (tx *DB) {
	tx = db.getInstance()
	if conds := tx.Statement.BuildCondition(query, args...); len(conds) > 0 {
		tx.Statement.AddClause(clause.Where{Exprs: conds})
	}
	return
}

func (db *DB) getInstance() *DB {
	if db.clone > 0 {
		tx := &DB{Config: db.Config, Error: db.Error}

		if db.clone == 1 {
			// clone with new statement
			tx.Statement = &Statement{
				DB:       tx,
				ConnPool: db.Statement.ConnPool,
				Context:  db.Statement.Context,
				Clauses:  map[string]clause.Clause{},
				Vars:     make([]interface{}, 0, 8),
			}
		} else {
			// with clone statement
			tx.Statement = db.Statement.clone()
			tx.Statement.DB = tx
		}
		return tx
	}
	return db
}
  • db.Open() 使db的clone=1
  • db.Begin() 使db的clone=1 (在https://github.com/go-gorm/gorm/pull/5012中修改为1,以前开启事务后clone是2)
  • db.Where() 使db的clone=0

使用Where前(重点!!!)

  • clone为1的话,是在新的数据库对象tx上构造查询条件(原db并没有修改),如果不接受Where()返回的tx,则会丢失构造的where条件;
  • clone为0的话,是在调用where的db对象本身上构造查询条件,所以可以不用接受Where()返回值;

使用场景

  1. clone为0时,构造同一条sql,db对象使用多个where。
  2. clone为1时,构造不同的sql,该db对象调用多个where,它本身的clone一直会是1。调用的where返回的tx的clone是0。那我们每条sql都是从最初的db调用的where的返回值(tx对象,clone=0)开始,然后又到了第一种情况。

一般的使用顺序:先使用 db.Open()或db.Begin()(返回了新的 db2)去开一条新 sql,再在这个db2 上使用 Where()构造这条 sql。

  • 19
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值