Java JPA和1000 ID在Oracle中的使用

Java JPA和1000 ID在Oracle中的使用,java,oracle,hibernate,jpa,oracle11g,Java,Oracle,Hibernate,Jpa,Oracle11g,我使用NamedNativeRequesty来删除行,它是这样的: DELETE from FAKTOR where ID IN ( select fa.ID from FAKTOR fa left join FAKTOR_REASON fars on fa.FARS_ID = fars.ID where fars.ID = 63 and fa.USER_ID in (:userIds)) 但是我怎样才能在Oracle的IN操作符中

我使用NamedNativeRequesty来删除行,它是这样的:

DELETE from FAKTOR
 where ID IN (
   select fa.ID
   from FAKTOR fa
     left join FAKTOR_REASON fars
       on fa.FARS_ID = fars.ID
   where fars.ID = 63
         and fa.USER_ID in (:userIds))
但是我怎样才能在Oracle的IN操作符中使用超过1000个用户ID呢


p.S:我正在寻找一种解决方案,在一次提交中处理它

在限制中绕过
是低效的,而且JPA并不总是适合这项工作的工具。考虑以下事项:

  • 数千个绑定值可能会产生兆字节的SQL。将此SQL发送到数据库需要很长时间。数据库读取SQL文本的时间可能比按照执行SQL文本的时间长

  • 由于SQL解析,这将是低效的。解析这个长SQL不仅需要很长时间,而且每个调用都有不同数量的绑定参数,这些参数将被单独解析和规划(请参阅)

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

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


    理想情况下,您可以用存储过程替换JPA,特别是如果您要从数据库中提取成千上万个标识符,以便在下一个查询中将它们传递回数据库

    我建议在java代码中对
    userid
    列表进行分区。Google Guava有
    list.partition
    方法,您可以在其中执行以下操作:

    List userIdsParts=Lists.partition(userIds,1000);
    
    然后可以将运算符中的
    的每个部分与
    连接起来:

    where ...
    and (fa.USER_ID in (:userIdsPart1) or fa.USER_ID in (:userIdsPart2) or ...)
    ...
    
    我建议使用查询生成器(如QueryDSL)来执行此逻辑,因为您通常不知道
    userid
    的大小,那么您就不知道列表将包含多少部分


    我希望我能帮助你

    @Karol Dowbecki是对的。这是有限度的,这是有原因的。有很多方法可以克服它。但您可能会陷入困境,否则DBA会不喜欢您。您还可以将Java数组作为Oracle集合传递,并将其与
    运算符的
    成员(或表集合表达式上的联接)一起使用。看到或感谢你,你是对的,但我们需要这个临时的,我们用本机查询替换它(不使用JPA);然后我们使用临时表,正如@karol dowbecki所说的。您应该使用一个子查询来选择这些ID,就像您最初从数据库中获取它们一样。它应该更快,因为这样您只需要发送一个查询供DB解析,而不是发送一个查询,检索数据,转换为Java,在两个方向上通过Hibernate,然后发送一个包含1000多个值的新查询来解析。