Java JPA和1000 ID在Oracle中的使用
我使用NamedNativeRequesty来删除行,它是这样的: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操作符中
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多个值的新查询来解析。