使用Spring Data JPA使用谓词和分页查询数据

时间:2014-06-19 23:53:34

标签: java spring oracle jpa spring-data

我有一段时间在Java工作的不幸,来自.net世界。抛开一边,我只是想实现一个可以处理谓词使用的存储库,并且必须具有分页功能。我无法找到一个好办法。

// IContactRepository.java
public interface IContactRepository extends Repository<Contact,Long> {

}
// Application.java
contactRepo.findAll(predicate, new PageRequest(0,10));

我希望能够找到包含搜索字词或包含搜索字词的联系电话号码的联系人姓名的联系人,然后获得前10场比赛。

在.net世界中,如果我没有使用orm,我会使用sql server的强大的TSQL来获得我想要的东西但是在这里坚持使用Oracle。否则我会使用一些ORM并将lambda作为谓词传递给查询函数。

3 个答案:

答案 0 :(得分:2)

在我的配置中,我也使用JPA和spring。 (对于静态预测。如果您想动态添加谓词(搜索词),请告诉我。)

// IContactRepository.java
public interface IContactRepository extends CrudRepository<Contact,Long>, PagingAndSortingRepository<Contact, Long>  {
    List<Contact> findByContactNameLikeAndContactPhoneLike(String name, String phone, Pageable pageable)
}

我尝试使用CrudRepo进行Pageable,它运行正常。 对于lambda你是对的:))

在我的配置中,您的实现如下所示:

IContactRepository contactRepo = context.getBean(IContactRepository.class);
List<Contacts> results = contactRepo.findByContactNameLikeAndContactPhoneLike("%CA%","%090%" , new PageRequest(1, 20));

http://docs.spring.io/spring-data/data-commons/docs/1.6.1.RELEASE/reference/html/repositories.html

请在 1.2.2定义查询方法

下查看查询创建

答案 1 :(得分:1)

我猜您正在查看Predicate,因为您希望能够执行任何任意复杂的查询。

但是没有findAll(Predicate, Pageable)方法。 我建议您查看SpecificationJpaSpecificationExecutor。你的代码看起来像这样:

public interface IContactRepository extends JpaRepository<Contact,Long>, JpaSpecificationExecutor<Contact> {

}

然后您可以访问方法findAll(Specification, Pageable)。根据您的要求,Specification是一个功能接口,因此您可以使用lambda轻松传入实现。

有关详细信息,请查看documentation中的2.5部分。

HereSpecification的Javadoc,而hereJpaSpecificationExecutor的Javadoc

此外,如果您不得不忍受Java的痛苦,您应该将I放在IContactRepository :)中。 Java代码通常会放弃.NET实践

答案 2 :(得分:1)

那我的实现可能会对您有所帮助:

@Override
public Page<Advert> findActiveAdverts(String searchValue, String availability, Long branchId, Long categoryId, Pageable pageable) {
    Page<Advert> adverts = advertRepository.findAll(new Specification<Advert>() {
        @Override
        public javax.persistence.criteria.Predicate toPredicate(Root<Advert> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
            List<Predicate> predicates = new ArrayList<>();

            predicates.add(cb.equal(root.get(Advert_.ACTIVE), true));

            if (!StringUtils.isEmpty(searchValue)) {
                predicates.add(cb.or(
                        cb.like(root.get(Advert_.TITLE), "%" + searchValue + "%"),
                        cb.like(root.get(Advert_.EXPLANATION), "%" + searchValue + "%"))
                );
            }

            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        }
    }, pageable);
    return adverts;
}