我使用Spring框架的jdbcTemplate来获取db的记录列表。现在我想通过在查询中附加约束来为其添加过滤。 例如。说该列表代表人物和节目 - 姓名,电子邮件和位置
原始查询是
String sql = "SELECT name, email, location FROM persons WHERE status = ?";
取决于过滤器,将附加约束
if(filters.containsKey("person_name")) {
sql += " AND name LIKE '%" + filters.get("person_name") + "%'";
}
//similarly
if(filters.containsKey("person_email")) {
....
}
//similarly
if(filters.containsKey("person_location")) {
....
}
因此,通过将查询传递给jdbcTemplate对象的查询方法来创建和执行查询
this.jdbcTemplate.query(sql, new Object[] { 1 }, RowMapper<Person> rowmapper)
我担心的是,通过使用上面的方法,它变得容易被注入,因为应用过滤器的值直接写入查询而没有任何转义。
是否可以动态创建第二个参数(参数数组),就像构建查询一样?
使用jdbcTemplate是否有替代方法?
修改 我现在使用org.apache.commons.lang.StringEscapeUtils中的StringEscapeUtils.escapeSql来转义值。但仍在寻找更好的方法或春天已经提供的方法。
谢谢
答案 0 :(得分:3)
我相信有更好的方法。拿你的代码
if (filters.containsKey("person_name")) {
sql += " AND name LIKE '%" + filters.get("person_name") + "%'";
}
并将其更改为
if (filters.containsKey("person_name")) {
sql += " AND name LIKE '%?%";
}
然后,您可以在查询方法中传入filters.get(“person_name”)。这将使您免受注射攻击。
回应评论
我也想到了这一点。但是如何 创建对象数组(新的 对象[] {..})动态吗?
您可以使用java.util.List并调用toArray()方法。有点像这样
import java.util.List;
import java.util.ArrayList;
List<Object> args = new ArrayList<Object>();
if (filters.containsKey("person_name")) {
sql += " AND name LIKE '%?%";
args.add(filters.get("person_name"));
}
然后当您需要将参数作为数组
时args.toArray();