SpringDataJpa针对ORACLE中IN长度不超过1000

  ORACLE针对SQLSELECT...FROM A WHERE A.ID IN(SELECT ID FROM B)是没有长度限制的,

但在JPA中IN长度超过1000就会报错,针对这种情况,我们可以将 IN的内容分隔,后再用OR连接,

废话不多说,直接上代码。

 public List<ComplaintsNotifyExportView> findByNotificationTyp(List<String> idList, NotificationType notificationType) {
        List<ComplaintsNotifyExportView> allList = complaintsNotifyExportViewDao.findAll(new Specification<ComplaintsNotifyExportView>() {
            @Override
            public Predicate toPredicate(Root<ComplaintsNotifyExportView> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicates = new ArrayList<Predicate>();
                List<Predicate> listOr = new ArrayList<Predicate>();
                Predicate [] predicateOr = null;
                if (CollectionUtils.isNotEmpty(idList)) {
                    Path<String> path = root.get("complaintsId");
                    if (idList.size() > MAX_LENGTH) {
                        List<List<String>> lists = segmentationList(idList, MAX_LENGTH-1);
                        for (List<String> list : lists) {
                            CriteriaBuilder.In<String> in = cb.in(path);
                            for (int i = 0; i < list.size(); i++) {
                                in.value(list.get(i));
                            }
                            listOr.add(in);
                        }
                        predicateOr = new Predicate[listOr.size()];
                    } else {
                        CriteriaBuilder.In<String> in = cb.in(path);
                        for (int i = 0; i <idList.size() ; i++) {
                            in.value(idList.get(i));
                        }
                        predicates.add(in);
                    }
                }
                if (null != notificationType) {
                    predicates.add(cb.equal(root.get("notificationType").as(NotificationType.class), notificationType));
                }
                Predicate [] predicateAnd = new Predicate[predicates.size()];
                if (predicateOr != null) {
                    return query.where(cb.and(predicates.toArray(predicateAnd)), cb.or(listOr.toArray(predicateOr))).getRestriction();
                } else {
                    return query.where(cb.and(predicates.toArray(predicateAnd))).getRestriction();
                }
            }
        });
        return allList;
    }


 public static List<List<String>> segmentationList(List<String> targe, int size) {
        List<List<String>> listArr = new ArrayList<List<String>>();
        // 获取被拆分的数组个数
        int arrSize = targe.size() % size == 0 ? targe.size() / size : targe
                .size() / size + 1;
        for (int i = 0; i < arrSize; i++) {
            List<String> sub = new ArrayList<String>();
            // 把指定索引数据放入到list中
            for (int j = i * size; j <= size * (i + 1) - 1; j++) {
                if (j <= targe.size() - 1) {
                    sub.add(targe.get(j));
                }
            }
            listArr.add(sub);
        }
        return listArr;
    }

猜你喜欢

转载自www.cnblogs.com/sly1994/p/11821915.html