【问题标题】:How to handle 999 size in Spring JDBC native Query IN parameter?如何处理 Spring JDBC 原生 Query IN 参数中的 999 大小?
【发布时间】:2018-07-25 16:46:41
【问题描述】:

我正在使用 Spring Batch + Spring JDBC。在我的项目中,我们将帐户列表传递给本机 SQL 的 IN 查询。在 IN 参数中,我们最多可以传递 999 条记录和我们再次需要处理的剩余列表。

我开发了以下代码,但如果我有超过 2000 条记录,则效果不佳。我怎样才能使动态,所以如果代码中有任何列表值应该生成结果?

if(accNumList.size() < 999) {
    Map<String, Set<Integer>> singletonMap = Collections.singletonMap("valSet1", accNumList);
    Map<String, Object> paramMap = new HashMap<>();
    paramMap.putAll(singletonMap);
    paramMap.put("isFlag", "Y");

    List<Map<String, Object>> queryForMap = namedParameterJdbcTemplate.queryForList(sql, paramMap);
}else {
    int sizeOfRecords = accNumList.size();
    // convert set to List
    List<Integer> data = new ArrayList<>(accNumList);
    List<Integer> subItems = data.subList(0, 999);

    Map<String, List<Integer>> singletonMap = Collections.singletonMap("valSet1", subItems);
    Map<String, Object> paramMap = new HashMap<>();
    paramMap.putAll(singletonMap);  
    List<Map<String, Object>> queryForMap = namedParameterJdbcTemplate.queryForList(sql, paramMap);

    // remaining
    int remaining = sizeOfRecords - 999;
    List<Integer> newsubItems = data.subList(1000, remaining);
    Map<String, List<Integer>> newsingletonMap = Collections.singletonMap("valSet1", newsubItems);

    Map<String, Object> newparamMap = new HashMap<>();
    newparamMap.putAll(newsingletonMap);

    List<Map<String, Object>> newqueryForMap = namedParameterJdbcTemplate.queryForList(sql, newparamMap);

    //final
    List<Map<String, Object>> queryForMapFinal = new ArrayList<>();
    queryForMapFinal.add(paramMap);
    queryForMapFinal.add(newparamMap);
}

【问题讨论】:

    标签: java oracle spring-jdbc


    【解决方案1】:

    绕过IN 限制效率低下,用Java 构建JDBC 查询并不总是适合这项工作的工具。考虑以下几点:

    1. 数以千计的绑定值可能会产生数兆字节的 SQL。将此 SQL 发送到数据库需要很长时间。数据库读取 SQL 文本的时间可能比按照 Tom's answer to "Limit and conversion very long IN list: WHERE x IN ( ,,, ...)" question 执行它的时间更长。

    2. 会因为SQL解析导致效率低下。不仅解析这么长的 SQL 需要很长时间,而且每次调用都有不同数量的绑定参数,这些参数将被单独解析和计划(参见this article which explains it)。

    3. SQL 语句中的绑定参数有硬性限制。您可以重复 OR 几次以绕过 IN 限制,但您将在某个时候达到 SQL 语句限制。

    对于这些类型的查询,通常最好创建temporary tables。在查询之前创建一个,将所有标识符插入其中,并将其与查询中的实体表连接起来,以模拟IN 条件。

    理想情况下,您可以用存储过程替换 Java 代码,尤其是当您从数据库中提取数以万计的标识符只是为了在下一个查询中将它们传回数据库时。

    【讨论】:

    • 在我的情况下,最多只能有 5000 行,我不想为此创建一个单独的表。 4轮999行程怎么办?
    猜你喜欢
    • 2015-10-17
    • 1970-01-01
    • 1970-01-01
    • 2018-10-08
    • 2014-01-19
    • 2011-04-14
    • 2019-05-27
    • 2012-06-28
    • 1970-01-01
    相关资源
    最近更新 更多