Java 如何使用Spring的JDBCTemplate有效地执行IN()SQL查询?
我想知道在使用Spring的JDBCTemplate进行查询时是否有更优雅的方法。目前我做的事情如下:Java 如何使用Spring的JDBCTemplate有效地执行IN()SQL查询?,java,sql,spring,jdbc,jdbctemplate,Java,Sql,Spring,Jdbc,Jdbctemplate,我想知道在使用Spring的JDBCTemplate进行查询时是否有更优雅的方法。目前我做的事情如下: StringBuilder jobTypeInClauseBuilder = new StringBuilder(); for(int i = 0; i < jobTypes.length; i++) { Type jobType = jobTypes[i]; if(i != 0) { jobTypeInClauseBuilder.append(',')
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());
}
这是非常痛苦的,因为如果我有九行代码只用于构建IN查询的子句。我想要一些类似于准备语句的参数替换的东西您想要一个参数源:
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());
这仅在getJdbcTemplate返回类型为的实例时有效。我使用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);
如果出现异常:列类型无效 请使用getNamedParameterJdbcTemplate而不是getJdbcTemplate 请注意,后两个参数是交换的 参见 使用命名参数编写查询,使用简单的ListPreparedStatementSetter并按顺序使用所有参数。只需添加以下代码片段,即可将基于传统形式的查询转换为可用参数 ParsedSql ParsedSql=NamedParameterUtils.parseSqlStatementnamedSql; 列表参数=新的ArrayList; A:A:B parameters.adda.getId; MapSqlParameterSource parameterSource=新的MapSqlParameterSource; parameterSource.AddValuePlaceholder 1,参数; //使用?'s创建SQL 字符串sql=NamedParameterUtils.substituteNamedParametersparsedSql,parameterSource; 返回sql;
自2009年以来,很多事情都发生了变化,但我只能找到答案说您需要使用NamedParametersJDBCTemplate 对我来说,如果我只做一个
db.query(sql, new MyRowMapper(), StringUtils.join(listeParamsForInClause, ","));
使用SimpleJDBCTemplate或JDBCTemplatePerfect,NamedParameterJdbcTemplate正是我想要的。此外,我更喜欢命名参数,而不是到处都是问号。谢谢!这适用于小列表,但尝试在大列表上使用它会导致以下查询:ids替换为?、?、?、?、?,?,?,?,?。。。。。。如果列表项足够多,它就会溢出。是否有一种适用于大型列表的解决方案?您可能应该将值插入到临时表中,并使用WHERE NOT EXISTS生成条件选择…,以删除答案:。但在参考文献中并没有提到:。奇怪,我得到了错误代码[17004];当我尝试此操作时,列类型无效。您刚刚发布了一个将近三年的问题的答案,其解决方案与已接受的答案相同。这背后有什么好的理由吗-这个答案更加清晰,因为它说明了此API需要NamedParameterJdbcTemplate。。。所以,谢谢你提供更多的细节janwen@janwen,谢谢你的解决方案!!!按照我的要求,它工作得很好!!这似乎不是这个问题的答案。这应该是对另一个答案的评论吗?@DaveSchweisguth两年后,它肯定是一个答案。这个解决方案的问题是,ListParamsForInClause中的内容不会被转义,并且使您容易受到SQL注入的攻击。对我来说,这是唯一有效的答案,因为我只想设置几个占位符
db.query(sql, new MyRowMapper(), StringUtils.join(listeParamsForInClause, ","));