2016-01-20 76 views
0

我必須使用過濾器實現搜索方法。這是結構:返回頁面定製的對象JpaRepository

我的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>。否則添加排序和分頁?

+0

你介意制定一個實際的問題嗎?你面臨哪個問題? –

+0

我的問題是是否有更簡單的方式來返回自定義搜索頁面。我不知道規格。 – oscar

回答

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);