10

这是我第一次使用 JDBCTemplates,我遇到了一个需要使用如下查询的情况:

SELECT * FROM table WHERE field IN (?)

我怎么做?我已经尝试过传递一个列表/数组值,但这并没有成功,我得到了一个例外。我当前的代码如下所示:

Long id = getJdbcTemplate().queryForLong(query, new Object[]{fieldIds});

Spring 文档指出,除了生成所需数量的“?”之外,没有其他方法可以做到这一点。占位符以匹配参数列表的大小。有解决方法吗?

4

5 回答 5

52

有一个使用NamedParameterJdbcTemplate而不是SimpleJdbcDaoSupport的解决方法,您可以在其中执行以下操作:

List integerList = Arrays.asList(new Integer[] {1, 2, 3});
Map<String,Object> params = Collections.singletonMap("fields", integerList);    
Long id = namedParameterJdbcTemplate.queryForLong("SELECT * FROM table WHERE field IN (:fields)", params);

但是,这对于您可以在列表中传递的参数数量具有潜在的灾难性限制,具体取决于您使用的数据库。

于 2010-12-22T15:04:48.990 回答
3

我认为您不能将其作为单个“?”来执行。它与 Spring JDBC 模板无关,它是核心 SQL。

您必须根据需要为它们中的任意数量建立一个 (?, ?, ?)。

于 2010-12-21T22:44:38.620 回答
3

对于长列表(例如 Oracle 有 1000 个项目的限制),您可以将其分隔为更多选择:

List<Long> listIds = Arrays.asList(1L, 2L, ..... , 10000L); // list with ids

String query = "select NOTE from NOTE where ID in (:listIds)";

List<String> noteListResult = new ArrayList<>();

int current = 0;
int iter = 100;

while (current < listIds.size()) {
    Map<String, List<Long>> noteIdsMap = Collections.singletonMap("listIds",
            listIds.subList(current, (current + iter > listIds.size()) ? listIds.size() : current + iter));

    List<String> noteListIter = namedParameterJdbcTemplate.queryForList(query, noteIdsMap, String.class);
    noteListResult.addAll(noteListIter);

    current += iter;
}

return noteListResult;
于 2016-02-25T14:43:58.750 回答
0

请尝试使用带有 NamedParameterJdbcTemplate 的 MapSqlParameterSource。

MapSqlParameterSource parameters = new MapSqlParameterSource();
    parameters.addValue("array", inputarray);
    NamedParameterJdbcTemplate jdbctemplate = new NamedParameterJdbcTemplate(
            this.jdbcTemplate.getDataSource());

查询中

输入(:数组)

于 2020-09-01T16:17:31.537 回答
-1

有一种方法可以做到,尽管我认为这不是最正确的。但我把它留在这里以防它帮助某人。

SELECT * FROM table WHERE field IN ("+array.toString()+")

以这种方式,jdbcTemplate 将查询作为完整的字符串读取并正确执行。

于 2021-12-30T14:33:16.497 回答