Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Criteria API使用NOT in语句读取数据块中的数据_Java_Sql_Db2_Eclipselink_Criteria Api - Fatal编程技术网

Java Criteria API使用NOT in语句读取数据块中的数据

Java Criteria API使用NOT in语句读取数据块中的数据,java,sql,db2,eclipselink,criteria-api,Java,Sql,Db2,Eclipselink,Criteria Api,我正在使用EclipseLink 2.6.4、Java8和DB2作为数据库。我必须编写查询来读取不在语句中的数据,该语句为不在语句提供大量值 基本上,我有一组超过10000个值的外部ID: Set<Integer> externalIDs = new HashSet<>(Arrays.asList("ExternalID1", "ExternalID2", "ExternalID3",....)); //externalIDs.size() == 10k+ 私有方法pa

我正在使用
EclipseLink 2.6.4
Java8
DB2
作为数据库。我必须编写查询来读取
不在
语句中的数据,该语句为
不在
语句提供大量值

基本上,我有一组超过10000个值的外部ID:

Set<Integer> externalIDs = new HashSet<>(Arrays.asList("ExternalID1", "ExternalID2", "ExternalID3",....)); //externalIDs.size() == 10k+
私有方法
partionedNotIn()
只是将
NOT IN
语句拆分为999个值的块,以使最大值不超过1000个

但正如您所看到的,我在语句中没有5个
,每提供10000个值,总共是50000个,我达到了托管可变长度的DB限制

无论如何,我们的目标是将其分块,这样我就不会在
语句中总共有50k+的
值,目前也不知道如何实现这一点。只要在
语句中使用
,就很容易了


任何建议都会有帮助。谢谢。

您从哪里获得不在的值?如果它是一个文件,那么您可能可以使用外部表。或者创建一个临时表,将值插入该表并在查询中使用。

将值存储在临时表中并根据它进行计算?!
public List<UserEntity> findNotReferencedToRemove2(Set<String> externalIds) {

  CriteriaBuilder cb = entityManager.getCriteriaBuilder();
  CriteriaQuery<UserEntity> cq = cb.createQuery(UserEntity.class);
  Root<UserEntity> root = cq.from(UserEntity.class);

  Path<String> externalId1 = root.get(UserEntity_.relation1).get(RelationEntity1_.externalId);
  Path<String> externalId2 = root.get(UserEntity_.relation2).get(RelationEntity2_.externalId);
  Path<String> externalId3 = root.get(UserEntity_.relation3).get(RelationEntity3_.externalId);
  Path<String> externalId4 = root.get(UserEntity_.relation4).get(RelationEntity4_.externalId);
  Path<String> externalId5 = root.get(UserEntity_.relation5).get(RelationEntity5_.externalId);

  Predicate predicate = cb.and(
      partitionedNotIn(cb, externalId1, externalIds),
      partitionedNotIn(cb, externalId2, externalIds),
      partitionedNotIn(cb, externalId3, externalIds),
      partitionedNotIn(cb, externalId4, externalIds),
      partitionedNotIn(cb, externalId5, externalIds)
  );

  return entityManager.createQuery(cq.where(predicate)).getResultList();
}

//creates NOT IN statement splited in chunks of 999 values connected with AND 
private<C> Predicate partitionedNotIn(CriteriaBuilder cb, Path<C> path, Collection<C> ids) {
    if (ids.isEmpty()) {
      return cb.and();
    }
    return cb.and(partition(ids).stream().map(path::in).map(cb::not).toArray(Predicate[]::new));
  }

  private <C> Collection<List<C>> partition(Collection<C> list) {
    final AtomicInteger counter = new AtomicInteger(0);
    return list.stream()
        .collect(Collectors.groupingBy(it -> counter.getAndIncrement() / 999))
        .values();
  }