如何在 JDBCTemplates 中使用 SELECT IN 子句?

发布于 2024-10-09 03:30:39 字数 441 浏览 6 评论 0原文

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

SELECT * FROM table WHERE field IN (?)

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

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

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

This is my first experience with JDBCTemplates and I ran into a case where I need to use a query that looks like this:

SELECT * FROM table WHERE field IN (?)

How do I do that? I already tried passing a list/array value but that didn't do the trick, I get an exception. My current code looks like this:

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

Spring Documentation states that there is no way of doing this besides generating the required number of "?" placeholders to match the size of the parameter List. Is there a workaround?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

俯瞰星空 2024-10-16 03:30:39

有一个解决方法,使用 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);

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

There is a workaround using NamedParameterJdbcTemplate instead of SimpleJdbcDaoSupport, where you can do something like this:

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);

This, however, has a potentially catastrophic limitation regarding the number of parameters you can pass in the list which depends on the DB you are using.

埖埖迣鎅 2024-10-16 03:30:39

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

您必须根据需要为尽可能多的对象建立 (?, ?, ?) 。

I don't think you can do this as a single '?'. It's nothing to do with Spring JDBC templates, it's core SQL.

You'll have to build up a (?, ?, ?) for as many of them as you need.

诗笺 2024-10-16 03:30:39

对于长列表(例如 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;

For long list (ex. Oracle has limitation for 1000 items) you can just separate it to more selects:

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;
别闹i 2024-10-16 03:30:39

请尝试使用 MapSqlParameterSource 和 NamedParameterJdbcTemplate。

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

在查询

IN (:array)中

Please try with MapSqlParameterSource with NamedParameterJdbcTemplate.

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

In query

IN (:array)

謸气贵蔟 2024-10-16 03:30:39

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

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

这样 jdbcTemplate 将查询作为完整的字符串读取并正确执行。

There is a way to do it although I don't think it is the most correct. But I leave it here in case it helps someone.

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

in this way jdbcTemplate reads the query as a complete string and it executes correctly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文