我有一个SQL像:
String sql = """SELECT id, name, sex, age, bron_year, address, phone, state, comment, is_hbp, is_dm, is_cva, is_copd, is_chd, is_cancer, is_floating, is_poor, is_disability, is_mental
FROM statistics_stin WHERE 1=1
${p.team_num == 0 ? "" : "AND team_num = ${p.team_num}"}
${p.zone == 0 ? "" : "AND team_id = ${p.zone}"}
${p.is_hbp == 2 ? "" : "AND is_hbp = ${p.is_hbp}"}
${p.is_dm == 2 ? "" : "AND is_dm = ${p.is_dm}"}
${p.is_chd == 2 ? "" : "AND is_chd = ${p.is_chd}"}
${p.is_cva == 2 ? "" : "AND is_cva = ${p.is_cva}"}
${p.is_copd == 2 ? "" : "AND is_copd = ${p.is_copd}"}
${p.is_cancer == 2 ? "" : "AND is_cancer = ${p.is_cancer}"}
${p.is_floating == 2 ? "" : "AND is_floating = ${p.is_floating}"}
${p.is_poor == 2 ? "" : "AND is_poor = ${p.is_poor}"}
${p.is_disability == 2 ? "" : "AND is_disability = ${p.is_disability}"}
${p.is_mental == 2 ? "" : "AND is_mental = ${p.is_mental}"}
${p.is_aged == 2 ? "" : (p.is_aged == 1 ? " AND age >= 65" : " AND age < 65")}
${p.is_prep_aged == 2 ? "" : (p.is_prep_aged == 1 ? "AND (age BETWEEN 60 AND 64)" : "AND (age < 60 OR age > 64)")}
${p.is_young == 2 ? "" : (p.is_young == 1 ? " AND age < 60" : " AND age >= 60")}
ORDER BY team_id ASC, id ASC
LIMIT ${start}, ${page_size}
""";
字符串
然后用途:
def datasource = ctx.lookup("jdbc/mysql");
def executer = Sql.newInstance(datasource);
def rows = executer.rows(sql);
型
这里p是一个json对象,如下所示:
p = {is_aged=2, is_cancer=2, is_chd=1, is_copd=2, is_cva=2, is_disability=2, is_dm=2, is_floating=2, is_hbp=1, is_mental=2, is_poor=2, pn=1, team_num=0, zone=0}
型
这种方式有SQL注入。我知道我可以使用参数类型,如:
executer.rows('SELECT * from statistics_stin WHERE is_chd=:is_chd', [is_chd: 1]);
型
但这种情况下有很多AND条件,使用与否将由json p决定。
请问怎么做?
2条答案
按热度按时间ars1skjm1#
你有一个动态SQL绑定的问题,即绑定参数的数量不是恒定的,而是取决于输入。
Tom Kyte提供了一个优雅的解决方案,它在Groovy中有更优雅的实现
其基本思想是简单的绑定所有变量,具有输入值并且应该使用的变量被正常处理,例如
字符串
没有输入的变量(应该被忽略)与一个虚拟结构绑定:
型
即,它们被快捷评估有效地忽略。
下面是三列的两个示例
型
此输入将导致完整查询
型
对于有限的输入
型
你会得到这个查询
型
这里Groovy创建的SQL语句
型
你甚至可以摆脱丑陋的
1=1
predicate ;)sz81bmfz2#
另一种选择是在构建查询时构建绑定,然后执行
rows
的适当实现字符串