-
Notifications
You must be signed in to change notification settings - Fork 9
SubWhere安全子查询
Tuuz edited this page Aug 9, 2023
·
5 revisions
使用方法: 1.创建语句,使用buildsql创建语句 2.使用db.SubWhere(field查询字段, condition查询模式, sql子查询语句,args子查询绑定参数) 完成子查询绑定 3.继续使用连续方法做其他查询 4.get或find方法取出数据
安全问题: 查看了TP的子查询方法,因为没有执行stmt,有被注入的可能,所以在设计sql方法的时候,特别考量了安全问题,因此你的每一次subQuery的生成和执行,均需要使用BuildSql方法生成语句和查询绑定条件才能保证安全
这将会生成一条语句:
SELECT * FROM `ps_school` WHERE `area_id` = (SELECT area_id FROM `ps_school` WHERE `id` = ? and `domain` = ?)
因为使用了参数化查询,所以可以在此基础上构建安全的查询方式
func Api_select_area_bySchoolId(id any) []gorose.Data {
db := tuuz.Db().Table(Table)
db.Fields("area_id")
db.Where("id", id)
db.Where("domain", "minshen")
sql, args, err := db.BuildSql("select")
if err != nil {
Log.DBrrsql(err, db, tuuz.FUNCTION_ALL())
return nil
}
db2 := tuuz.Db().Table(Table)
db2.SubWhere("area_id", "=", sql, args)
ret, err := db2.Get()
fmt.Println(db2.LastSql())
if err != nil {
Log.DBrrsql(err, db, tuuz.FUNCTION_ALL())
return nil
} else {
return ret
}
}
这个查询方式将有概率破坏IndexCondition,这将大大降低你程序的性能,但是这能降低Mysql到你程序间的TCP浪费,所以使用程序法还是DB法解决问题,需要考量你当前的需求和数据量。
- 大库数据量大的情况下,优先考虑使用程序法
- 过程多,多次回转查询需求或降级In查询,可以考虑使用SubWhere方法
- 小库小数据量大查询量,有回转查询的需求,可以使用SubWhere方法
- Index Condition 降级,Where Condition降级,数据量小的情况下,并有降低代码量的需求,优先使用SubWhere方法