返回页面对象与自定义JpaRepository

时间:2016-01-20 19:30:17

标签: java spring jpa spring-data

我必须使用过滤器实现搜索方法。这是结构:

我的Jpa界面:

public interface FooRepository extends JpaRepository<Foo, Long>, FooRepositoryCustom {
}

我的自定义界面:

public interface FooRepositoryCustom {
    Page<Foo> findByFilter(FooFilter filter, Pageable pageable);
}

我的自定义实现:

public class FooRepositoryImpl implements FooRepositoryCustom {

    @PersistenceContext
    private EntityManager em;

    @Override
    public Page<Foo> findByFilter(FppFilter filter, Pageable pageable) {

        CriteriaQuery<Foo> criteriaQuery = em.getCriteriaBuilder().createQuery(Foo.class);
        Root<Foo> root = criteriaQuery.from(Foo.class);
        criteriaQuery.select(root);

        List<Predicate> predicates = new ArrayList<Predicate>();

        if (filter.getFooAttr1() != null) {
            predicates.add(em.getCriteriaBuilder().equal(root.get("fooAttr1"), filter.getFooAttr1()));
        }

        if (filter.getOtherFooId() != null) {
            Join<Foo, OtherFoo> join = root.join("otherFoo", JoinType.LEFT);
            predicates.add(em.getCriteriaBuilder().equal(join.get("id"), filter.getOtherFooId()));
        }

        criteriaQuery.where(predicates.toArray(new Predicate[] {}));

        // Order
        List<Order> orderList = new ArrayList<Order>();
        for (org.springframework.data.domain.Sort.Order order : pageable.getSort()) {
            if (order.getDirection().equals(Direction.ASC)) {
                orderList.add(em.getCriteriaBuilder().asc(root.get(order.getProperty())));
            } else {
                orderList.add(em.getCriteriaBuilder().desc(root.get(order.getProperty())));
            }
        }
        criteriaQuery.orderBy(orderList);

        int totalRows = em.createQuery(criteriaQuery).getResultList().size();
        em.createQuery(criteriaQuery).setFirstResult(pageable.getPageNumber() * pageable.getPageSize());
        em.createQuery(criteriaQuery).setMaxResults(pageable.getPageSize());
        Page<Foo> page = new PageImpl<Foo>(em.createQuery(criteriaQuery).getResultList(), pageable, totalRows);

        return page;
    }

}

有一种简单的方法可以在没有条件的情况下返回Page <Foo>。否则要添加排序和分页?

1 个答案:

答案 0 :(得分:0)

我不知道规格。 这是我的解决方案

我实施了我的espeficicación:

public class FooSpecifications {

    public static Specification<Foo> withFilter(final FooFilter filter) {
        return new Specification<Foo>() {
            @Override
            public Predicate toPredicate(Root<Foo> root, CriteriaQuery<?> query,
                    CriteriaBuilder builder) {

                List<Predicate> predicates = new ArrayList<Predicate>();

                if (filter.getAttr1() != null) {
                    predicates.add(builder.equal(root.get("attr1"), filter.getAttr1()));
                }

                if (filter.getOtherFooId() != null) {
                    Join<Foo, OtherFoo> join = root.join("otherFoo", JoinType.LEFT);
                    predicates.add(builder.equal(join.get("id"), filter.getOtherFooId()));
                }

                return builder.and(predicates.toArray(new Predicate[] {}));
            }
        };
    }

}

我将方法添加到界面:

public interface FooRepository extends JpaRepository<Foo, Long>, FooRepositoryCustom {

    Page<Foo> findAll(Specification<Foo> specification, Pageable pageable);
}

并在服务中使用:

fooRepo.findAll(FooSpecifications.withFilter(filter), pageable);