获取GORM执行时的sql字符串

基础示例:

import (
	"fmt"
)
func GetUserDetailSql(tx *gorm.DB,id int,data model)(sql string){
	var query = tx.Session(&gorm.Session{DryRun: true})
	var querySmt= query.Where("id = ?", id).First(&data).Statement
	sql=sqlStm.Dialector.Explain(sqlStm.SQL.String(), sqlStm.Vars...)
	fmt.Println("执行的sql:",sql)
}

注意事项

  1. 执行前需要事先声明Session,将DryRun设置为true;
  2. 执行完First、Find、Delete 等方法后拿到Statement对象去获取sql语句;
  3. DryRun设置为true以后,只会组建SQL语句,不会执行数据库操作

使用技巧

此方法可以配合scopes组建复杂的SQL查询语句

type QueryUserTableBuidler{
	SelectFileds []string
}
func (q *QueryUserTableBuidler)Build(params *queryUserParams,tx *gorm.DB)(sql string,err error){
		var baseTable = `SELECT  su.id user_id, rn.name real_name, su.tel_num, rn.id_num FROM sys_suer su 
		Left JOIN real_name rn ON su.real_name_id = rn.id AND rn.deleted_at =0 
		WHERE su.deleted_at =0`
		//处理基础表的字段筛选
		if params.IdNum!= "" {
			base += fmt.Sprintf("AND su.id_num = '%s'", params.IdNum)
		}
		if params.Sex != "" {
			base += fmt.Sprintf("AND rn.sex = '%s'", params.Sex)
		}
		//生成基础表t
		tx.Table(fmt.Sprintf("(%s) AS t"),baseTable )
	    q.SelectFields = append(q.SelectFields, "t.user_id","t.real_name","t.tel_num","t.id_num")
		//加载关联表
		tx = tx.Scopes(
			q.JoinsShowStatScope(),//可以添加多个关联查询
			)
		//生成Sql
		var query = tx.Session(&gorm.Session{DryRun: true})
		var querySmt= query.Select(strings.Join(q.SelectFields,",")).Where("id = ?", id).First(&view.UserStat).Statement
		sql=sqlStm.Dialector.Explain(sqlStm.SQL.String(), sqlStm.Vars...)
		fmt.Println("sql:",sql)
		return
}
func (q*QueryUserTableBuidler) JoinsShowStatScope(params *queryUserParams) func(tx*gorm.DB) *gorm.DB {
	//select中添加此关联sql对外的字段
	q.SelectFields = append(q.SelectFields, `IFNULL(show_stat.show_count,0) show_count`)
	return func(tx*gorm.DB) *gorm.DB {
	    var sql=`LEFT JOIN ( SELECT user_id,COUNT(id) show_count FROM user_show WHERE IFNULL(deleted_at,0)=0 AND is_show >= 3 %s GROUP BY user_id ) show_stat ON  t.user_id = show_stat.artist_uid`
	    var where string
	    if params.UserId!=0{
	    	where +=fmt.Sprintf("AND user_id = %d",params.UserId)
	    }
	    sql=fmt.Sprintf(sql,where)
		tx=tx.Joins(sql)
		return tx
	}
}

使用

func QueryUserStat(params *queryUserParams)(res []*view.UserStat,err error)
	sqlRaw ,err := new(QueryUserTableBuidler).Build(params, db.DB)
	if err!=nil{
		return err
	}
	tx = db.DB.Table(fmt.Sprintf("(SELECT * FROM (%s) tt ) tt", sqlRaw ))
	if params.IdNum!=""{
		tx=tx.Where("id_num = ?",params.IdNum)
	}
	err=tx.Find(&res).Err
	return
  1. 模块化的JOIN语句 ,易于组装,适合快速的功能迭代。可以快速对Join语句进行增删。
  2. 易于优化SQL的执行速度。示例中的QueryUserTableBuidler,使用了查询参数,对局部sql进行了优化,从而提升了查询速度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值