使用squirrel进行sql拼接不生效问题及解决
作者:love666666shen
这篇文章主要介绍了使用squirrel进行sql拼接不生效问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
使用squirrel拼接sql不生效
拼接sql的时候,一般使用同一个变量不断拼接连接。
但是,在使用github.com/Masterminds/squirrel包进行sql拼接时,
需要多加注意:在使用变量添加sql语句后,还需要重新再赋值给该变量,否则达不到想要的结果。
如下代码:
import sq "github.com/Masterminds/squirrel" func FindProviderProduct(providerID int, keyWord string) (products []*ProductInfo, err error) { db, err := GetDB() if err != nil { return } buffer := sq.Select("PP.product_id", "P.product_name").From("provider_product as PP"). LeftJoin("provider as PV on PV.id = PP.provider_id"). LeftJoin("product as P on P.id = PP.product_id"). Where(sq.Eq{"P.is_deleted": 0, "PV.is_deleted": 0}) if providerID != 0 { buffer.Where(sq.Eq{"PP.provider_id": providerID}) // 这里拼接完sql后,没有重新赋值给buffer变量,相当于这句sql没有拼接到原buffer语句中 } keyWord = easy.ReplaceSpecialStr(keyWord) if len(keyWord) != 0 { buffer.Where(sq.Like{"P.product_name": keyWord}) // 这里拼接完sql后,没有重新赋值给buffer变量,相当于这句sql没有拼接到原buffer语句中 } sqlStr, args, _ := buffer.ToSql() if err = db.Debug().Raw(sqlStr, args...).Find(&products).Error; err != nil { return } return }
上面的代码,在进行如下赋值后:
buffer := sq.Select("PP.product_id", "P.product_name").From("provider_product as PP"). LeftJoin("provider as PV on PV.id = PP.provider_id"). LeftJoin("product as P on P.id = PP.product_id"). Where(sq.Eq{"P.is_deleted": 0, "PV.is_deleted": 0})
即使,后面的两个if语句满足条件,但是没有将其中的sql重新赋值给buffer变量,也不会把if里面的筛选条件添加到buffer中,
最终的sql结果仅仅是如下sql:
SELECT PP.product_id, P.product_name FROM provider_product as PP LEFT JOIN provider as PV on PV.id = PP.provider_id LEFT JOIN product as P on P.id = PP.product_id WHERE P.is_deleted = 0 AND PV.is_deleted = 0;
解决方式
在两个if条件中,处于使用buffer继续添加筛选条件外,还需要将添加后的筛选条件重新赋值给buffer变量即可。
修改后的代码如下:
import sq "github.com/Masterminds/squirrel" func FindProviderProduct(providerID int, keyWord string) (products []*ProductInfo, err error) { db, err := GetDB() if err != nil { return } buffer := sq.Select("PP.product_id", "P.product_name").From("provider_product as PP"). LeftJoin("provider as PV on PV.id = PP.provider_id"). LeftJoin("product as P on P.id = PP.product_id"). Where(sq.Eq{"P.is_deleted": 0, "PV.is_deleted": 0}) if providerID != 0 { buffer = buffer.Where(sq.Eq{"PP.provider_id": providerID}) // 这里在使用buffer拼接后,需要重新赋值给buffer } keyWord = easy.ReplaceSpecialStr(keyWord) if len(keyWord) != 0 { buffer = buffer.Where(sq.Like{"P.product_name": keyWord}) // 这里在使用buffer拼接后,需要重新赋值给buffer } sqlStr, args, _ := buffer.ToSql() if err = db.Debug().Raw(sqlStr, args...).Find(&products).Error; err != nil { return } return }
使用squirrel中的First
squirrel中的First取1条查询数据,相当于在查询结果中添加limit 1。
例如,现有如下sql拼接:
SELECT IFNULL(MAX(update_time), 0) as max_update_time FROM product WHERE user_id = xxx AND product_status IN (1,2)
现对如上sql使用First方法,相当于:
SELECT IFNULL(MAX(update_time), 0) as max_update_time FROM product WHERE user_id = xxx AND product_status IN (1,2) LIMIT 1
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。