如何有效地使用Spring的JDBCTemplate执行IN()SQL查询?

Mal*_*lax 172 java sql spring jdbc jdbctemplate

我想知道是否有一种更优雅的方式来使用Spring的JDBCTemplate进行IN()查询.目前我做的是这样的:

StringBuilder jobTypeInClauseBuilder = new StringBuilder();
for(int i = 0; i < jobTypes.length; i++) {
    Type jobType = jobTypes[i];

    if(i != 0) {
        jobTypeInClauseBuilder.append(',');
    }

    jobTypeInClauseBuilder.append(jobType.convert());
}
Run Code Online (Sandbox Code Playgroud)

这是非常痛苦的,因为如果我有九行只是为IN()查询构建子句.我想要像准备语句的参数替换

yaw*_*awn 258

你想要一个参数来源:

Set<Integer> ids = ...;

MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("ids", ids);

List<Foo> foo = getJdbcTemplate().query("SELECT * FROM foo WHERE a IN (:ids)",
     parameters, getRowMapper());
Run Code Online (Sandbox Code Playgroud)

这仅在getJdbcTemplate()返回类型的实例时有效NamedParameterJdbcTemplate

  • 奇怪的是,当我尝试这个时,我得到"错误代码[17004];无效的列类型". (9认同)
  • 要回答:[Spring 3.1 Reference - 传入IN子句的值列表](http://static.springsource.org/spring/docs/3.1.0.RELEASE/reference/html/jdbc.html#jdbc-in -条款).但在Reference中没有说到:[可以通过任何收集](http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.jdbc/3.0.6/org/ springframework的/ JDBC /核心/ namedparam/NamedParameterUtils.java /#206). (6认同)
  • 完美,NamedParameterJdbcTemplate正是我想要的.另外,我喜欢命名参数比那些问号更多.非常感谢! (5认同)
  • 这适用于小型列表,但尝试在大型列表中使用它会导致查询:ids被替换为"?,?,?,?,?......"并且有足够的列表项溢出.有适用于大型列表的解决方案吗? (5认同)
  • 我花了几个小时寻找解决方案,在传统 JdbcTemplate 和参数化 Jdbc 模板之间来回切换我的代码。我喜欢这个解决方案,因为 Java Set Collection 保证了所添加的 ID 键的内置唯一性。它还优于手动构建表示逗号分隔的 ID 系列的字符串。谢谢你! (2认同)

jan*_*wen 55

我用spring jdbc执行"in子句"查询,如下所示:

String sql = "SELECT bg.goodsid FROM beiker_goods bg WHERE bg.goodsid IN (:goodsid)";

List ids = Arrays.asList(new Integer[]{12496,12497,12498,12499});
Map<String, List> paramMap = Collections.singletonMap("goodsid", ids);
NamedParameterJdbcTemplate template = 
    new NamedParameterJdbcTemplate(getJdbcTemplate().getDataSource());

List<Long> list = template.queryForList(sql, paramMap, Long.class);
Run Code Online (Sandbox Code Playgroud)

  • 这个答案提供了更清晰的说明,因为它说明了这个API需要NamedParameterJdbcTemplate ...所以感谢janwen的额外细节 (15认同)
  • 您刚刚使用与已接受的答案相同的解决方案发布了对近三年的问题的答案.这背后有什么好理由吗?:-) (9认同)
  • 也许我会显示这个问题的更多细节. (5认同)

小智 16

如果您收到以下异常:无效的列类型

请使用getNamedParameterJdbcTemplate()而不是getJdbcTemplate()

 List<Foo> foo = getNamedParameterJdbcTemplate().query("SELECT * FROM foo WHERE a IN (:ids)",parameters,
 getRowMapper());
Run Code Online (Sandbox Code Playgroud)

请注意,后两个参数是交换的.

  • 这似乎不是这个问题的答案.它应该是对另一个答案的评论吗? (2认同)
  • @DaveSchweisguth两年后,它绝对值得回答. (2认同)