如果我在引号中有很多东西,我发现自己在做类似的事情:
String sql = "SELECT col1, col2, col3 "
+ "FROM my_awesome_table "
+ "WHERE strValue IN (%s)";
sql = String.format(sql, COMMA_JOINER.join(Iterables.transform(strValues,
new Function<String, String>() {
@Override
public String apply(String input) {
return "'" + input.replaceAll("'", "''") + "'";
}
})));
List<ResultObject> resultObjects =
getSimpleJdbcTemplate().query(sql, resultObjectRowMapper());
但似乎很奇怪我必须构建自己的IN子句,用单引号括起字符串,然后自己逃避它们。必须有更好的方式!一些额外的上下文:我不希望查询太多(最多几十行或几百行),只要我们不一次查询一行,优化就不是太大的问题!
答案 0 :(得分:4)
首先,即使没有JdbcTemplate,您也应该使用预准备语句,从而让JDBC驱动程序为您提取引号。 SQL查询类似于
select ... where strValue in (?, ?, ?, ?)
并且您将使用PreparedStatement.setParameter()
绑定每个参数,而无需转义任何内容。
使用NamedParameterJdbcTemplate,它更容易,因为Spring允许对整个字符串集合使用单个参数。它的用法在Spring documentation:
中有解释String sql = "select ... from ... where strValue in :listOfValues";
Map namedParameters = Collections.singletonMap("listOfValues", strValues);
...
答案 1 :(得分:2)
根据this thread on springsource,以下内容应该有效:
String sql = "SELECT col1, col2, col3 "
+ "FROM my_awesome_table "
+ "WHERE strValue IN (:items)";
getSimpleJdbcTemplate().query(
sql
, Collections.singletonMap("items", strValues)
, resultObjectRowMapper()
);