ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

gorm的子句构造

2021-05-19 17:34:52  阅读:390  来源: 互联网

标签:clause sql db 构造 elfilter 子句 Where gorm


gorm为我们提供了很多方法便捷我们的操作,例如 Where、Model、Update。。。等等,这些方法最终都是走到了gorm的构建器,详情见:
https://gorm.io/zh_CN/docs/sql_builder.html
在某些时候我们可能需要自己去构建sql语句提供两个参考:
参考一
冷热表查询联合查询,可使用 Union/Union All,我这里两个表结构完全相同

elfilter := exchangeDBClient.Table("")
	//使用提供的方法,构建查询条件
	elfilter = elfilter.Where("exchange_id = ?", EID)
	if req.Start > 0 {
		start := time.Unix(Start, 0)
		elfilter = elfilter.Where("created_at >= ?", start)
	}
	if End > Start {
		end := time.Unix(End, 0)
		elfilter = elfilter.Where("created_at < ?", end)
	}
	if Category != nil && len(Category)>0 {
		elfilter = elfilter.Where("category in (?)", Category)
	}
	if req.CoinCode != "" {
		elfilter = elfilter.Where("coin_code = ?", CoinCode)
	}
	sqls := make([]string, 0)
	for _, suf := range tableSuffix {
		tableName := strings.ToLower(fmt.Sprintf("ledger_%d_%s", EID, suf))
		elfilter.Table(tableName)
		//手动调用内部的构建查询语句的回调函数,使用Find()方法时,其实就会调用这个回调函数
		callbacks.BuildQuerySQL(elfilter)
		//获取构造出的查询sql语句
		querySql := elfilter.Statement.Dialector.Explain(elfilter.Statement.SQL.String(), elfilter.Statement.Vars...)
		//当Statement.SQL设置过后,如果不reset,将不会设置新的
		elfilter.Statement.SQL.Reset()
		sqls = append(sqls, querySql)
	}
	//拼接最终的sql语句
	sql := strings.Join(sqls, " UNION ALL ")
	db := exchangeDBClient.Table("")
	db.Statement.SQL.WriteString(sql)
	records := make([]*Test, 0)
	//这里还能添加上一些其他的查询条件,手写sql语句了相当于
	db = exchangeDBClient.Raw(fmt.Sprintf("%s order by created_at asc offset %d limit %d", sql, (page.PageNum-1)*page.PageSize, page.PageSize))
	err = db.Find(&records).Error
	if err != nil {
		return nil, nil, err
	}

参考二
当使用 postgreSQL的时候,因为postgres支持returning(即postgresql 的 returning特性可以返回DML(insert、update、delete)修改的数据。),当我们update的时候想要获取更新后的值,而又不想再查一遍消耗系统性能时,使用

colums := []clause.Column{
		{Name: "id"},
		{Name: "name"},
		{Name: "age"},
		{Name: "class"},
	}

	returning := clause.Returning{
		Columns: colums,
	}

	//where := []clause.Expression{clause.Eq{Column: "id", Value: "1"}}

	se := new(postgreSQL.BaseStr)
	//se.ID = 1
	//se.Name = "王二麻子"
	//se.Age = 444
	//se.Class = 123124

	var settings []clause.Assignment
	settings = append(settings, clause.Assignment{Column: clause.Column{Name: "age"}, Value: gorm.Expr("age + ?", 444)})

	db := postclient.Debug().Table("base_strs").Where("id = ?",1)
	db = db.Clauses(
		clause.Update{},
		clause.Set(settings),
		//clause.Where{where},
		returning)
	db.Statement.Build("UPDATE", "SET", "WHERE","RETURNING")
	db.First(&se)
	fmt.Println(se)

db.Clauses可以组装任意字句,在最终Build的时候,把关键字填入即可。也可以把gorm提供的方法和自己构造的字句一起使用,但是,在Build中还是需要将所有使用到的关键字都要加上,否则调用的gorm方法将不起作用。如例中,Build中去掉 “WHERE”,则调用的 .WHERE(“id = ?”,1) 不生效。这是因为,原本gorm是帮你生成了子句,并build了,但是当你自己手动build的时候,gorm就会走到你的build流程,gorm提供的子句构造就不会往下走,如果不指定关键字,则对应的子句就不会 构造到最终的sql语句中。

标签:clause,sql,db,构造,elfilter,子句,Where,gorm
来源: https://blog.csdn.net/weixin_45244610/article/details/117035887

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有