Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用Spring的JDBCTemplate有效地执行IN()SQL查询?_Java_Sql_Spring_Jdbc_Jdbctemplate - Fatal编程技术网

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

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(',')

我想知道在使用Spring的JDBCTemplate进行查询时是否有更优雅的方法。目前我做的事情如下:

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或JDBCTemplate

Perfect,NamedParameterJdbcTemplate正是我想要的。此外,我更喜欢命名参数,而不是到处都是问号。谢谢!这适用于小列表,但尝试在大列表上使用它会导致以下查询:ids替换为?、?、?、?、?,?,?,?,?。。。。。。如果列表项足够多,它就会溢出。是否有一种适用于大型列表的解决方案?您可能应该将值插入到临时表中,并使用WHERE NOT EXISTS生成条件选择…,以删除答案:。但在参考文献中并没有提到:。奇怪,我得到了错误代码[17004];当我尝试此操作时,列类型无效。您刚刚发布了一个将近三年的问题的答案,其解决方案与已接受的答案相同。这背后有什么好的理由吗-这个答案更加清晰,因为它说明了此API需要NamedParameterJdbcTemplate。。。所以,谢谢你提供更多的细节janwen@janwen,谢谢你的解决方案!!!按照我的要求,它工作得很好!!这似乎不是这个问题的答案。这应该是对另一个答案的评论吗?@DaveSchweisguth两年后,它肯定是一个答案。这个解决方案的问题是,ListParamsForInClause中的内容不会被转义,并且使您容易受到SQL注入的攻击。对我来说,这是唯一有效的答案,因为我只想设置几个占位符
db.query(sql, new MyRowMapper(), StringUtils.join(listeParamsForInClause, ","));