如何在JPA中处理分页(条件和谓词)

时间:2018-09-27 12:59:49

标签: java hibernate spring-data-jpa hibernate-criteria

我正在使用条件和谓词从数据库中获取结果,并且得到了结果列表,并且我尝试应用分页和排序,但是它不起作用。请在我想念的地方帮我,这是我的代码:

private Page<Books> getFiltereBooks(Params params,
            PageRequest sortOrder) {
        CriteriaBuilder builder =  em.getCriteriaBuilder();
        CriteriaQuery<Books> criteria = builder.createQuery(Books.class);
        Root<Books> booksRoot = criteria.from(Books.class);
        List<Predicate> predicates = new ArrayList<Predicate>();


            predicates.add(builder.equal(booksRoot.get("id"), params.getRequestId()));


            predicates.add(builder.like(builder.lower(booksRoot.get("name")), 
                    "%" + params.getName().toLowerCase() + "%"));


        criteria.where(builder.and(predicates.toArray( new Predicate[predicates.size()])));

            criteria.orderBy(builder.desc(booksRoot.get("id")));

        List<Books> result = em.createQuery(criteria).getResultList();
        int total = result.size();
        Page<Books> result1 = new PageImpl<>(result, sortOrder, total);
        return result1;
    }

当我使用此代码时:

Page<Books> result1 = new PageImpl<>(result, sortOrder, total);

它不起作用,我想返回一个页面对象。任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:4)

您可以尝试

private Page<Books> getFiltereBooks(Params params,
            Pageable pageable) {

        CriteriaBuilder builder =  em.getCriteriaBuilder();
        CriteriaQuery<Books> criteria = builder.createQuery(Books.class);
        Root<Books> booksRoot = criteria.from(Books.class);
        List<Predicate> predicates = new ArrayList<Predicate>();

        predicates.add(builder.equal(booksRoot.get("id"), params.getRequestId()));

        predicates.add(builder.like(builder.lower(booksRoot.get("name")), 
                    "%" + params.getName().toLowerCase() + "%"));

        criteria.where(builder.and(predicates.toArray( new Predicate[predicates.size()])));

        criteria.orderBy(builder.desc(booksRoot.get("id")));

        // This query fetches the Books as per the Page Limit
        List<Books> result = em.createQuery(criteria).setFirstResult((int) pageable.getOffset()).setMaxResults(pageable.getPageSize()).getResultList();

        // Create Count Query
        CriteriaQuery<Long> countQuery = builder.createQuery(Long.class);
        Root<Books> booksRootCount = countQuery.from(Books.class);
        countQuery.select(builder.count(booksRootCount)).where(builder.and(predicates.toArray(new Predicate[predicates.size()])));

        // Fetches the count of all Books as per given criteria
        Long count = em.createQuery(countQuery).getSingleResult();

        Page<Books> result1 = new PageImpl<>(result, pageable, count);
        return result1;
    }

答案 1 :(得分:0)

Predicate[] getPredicate(Root<Entity> root, CriteriaBuilder criteriaBuilder, filter params) {
    Predicate[] predicatesArr = null;
    List<Predicate> predicates = new ArrayList<>();
    
    // fill your predicates list here

    predicatesArr = predicates.toArray(new Predicate[predicates.size()]);

    return predicatesArr;
}

您需要添加一个为每个查询创建谓词的方法,注意这里您使用相同的谓词列表“从不同的查询驱动”两个查询[分页和计数]

    Root<Books> booksRoot = criteria.from(Books.class);
    predicates.add(builder.equal(booksRoot.get("id"), params.getRequestId()));