Spring Data Repository动态查找器Oracle In子句最大值为1000

时间:2016-02-12 14:26:36

标签: java spring oracle spring-data

我想知道是否有一种机制可以将超过1000个项目的集合处理到Spring Repository中以获取SQL IN子句。现在,我们在将项目列表传递到存储库之前拆分项目列表,但是如果驱动程序或弹簧知道Oracle的限制会很好,并且会为我们工作。

2 个答案:

答案 0 :(得分:8)

解决IN限制效率低下,Spring Data并非总是适合此工作的合适工具。请考虑以下内容:

  1. 数千个绑定值将导致潜在的兆字节SQL。将此SQL发送到数据库将花费很长时间。数据库可能比根据Tom's answer to "Limit and conversion very long IN list: WHERE x IN ( ,,, ...)" question执行SQL文本花费的时间更长。

  2. 由于SQL解析,效率低下。

  3. 不仅解析此长的SQL需要花费很长时间,而且每次调用都有不同数量的绑定参数,这些参数将分别解析和计划(请参阅this article which explains it)。

  4. SQL语句中对绑定参数有硬限制。您可以重复执行OR几次,以达到IN的限制,但有时会达到SQL语句的限制。

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

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

答案 1 :(得分:4)

  1. 创建一个临时表:

    CREATE GLOBAL TEMPORARY TABLE table_name
    ( value column_data_type
    ) ON COMMIT DELETE ROWS;
    

    您的代码将用于IN子句的所有值的记录插入到临时表中。

    您可以使用IN来代替列出IN (select value from table_name)中的所有值。

  2. 由于容器中的会话或事务管理,您可能会遇到麻烦。如果无法轻松处理,则可以创建一个带有标识符

    的普通表。
    CREATE TABLE table_name
    ( identifier number, value column_data_type
    );
    

    您还需要一个序列来生成标识符。

    您的代码将具有特定标识符的IN子句使用的所有值的记录插入表中。

    您可以使用IN (select value from table_name where identifier = ?)