Spring Data Jpa 动态查询Specification的基本用法

在平常的使用中,我们往往要根据前端传过来的参数(参数个数不确定)动态查询一些数据。

下文就介绍一下在Spring Data Jpa中动态查询的基本用法。

一、dao层的Repository继承JpaRepository

例:

public interface UserInfoRepository extends JpaRepository<T, Long>, JpaSpecificationExecutor<T> {
}

二、在需要查询的service类中注入Repository 
例:

@Resource
private UserInfoRepository userInfoRepository;

三、在需要查询的方法中使用动态查询

1、查询全部findAll

下面介绍最常用的(equal,notEqual,in,like,greaterThan,lessThan,between,le,ge,isNotNull,isNull)用法。

注意:r.get("xxx")里面的字段必须是实体类里面存在的且必须一致

public void queryUserInfo (String userCode, List<String> unionNoList, String userName, Date startTime, Date endTime, Integer maxAge, Integer minAge, String sex) {
        List<UserInfoEntity> userInfoList = = userInfoRepository.findAll((Specification<UserInfoEntity>) (r, q, b) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (StringUtils.isNotBlank(userCode)) {
                //equal等于
                predicates.add(b.equal(r.get("userCode"), userCode));
            }
            if (StringUtils.isNotBlank(sex)) {
                //notEqual不等于
                predicates.add(b.notEqual(r.get("sex"), sex));
            }
            if (!CollectionUtils.isEmpty(unionNoList)) {
                //in多个查询
                predicates.add(r.get("unionNo").in(unionNoList));
            }
            if (StringUtils.isNotBlank(userName)) {
                //like模糊查询
                predicates.add(b.like(r.get("userName"), "%" + userName + "%"));
            }
            if (null != startTime) {
                //greaterThanOrEqualTo大于等于, greaterThan大于
                predicates.add(b.greaterThan(r.get("createdTime"), startTime));
            }
            if (null != endTime) {
                //lessThanOrEqualTo小于等于, lessThan小于
                predicates.add(b.lessThan(r.get("createdTime"), endTime));
            }
            if (null != maxAge && null != minAge) {
                //between
                predicates.add(b.between(r.get("age"), minAge, maxAge));
            }
            if (null != maxAge) {
                //le小于(用于判断数字)
                predicates.add(b.le(r.get("age"), maxAge));
            }
            if (null != minAge) {
                //ge大于(用于判断数字)
                predicates.add(b.ge(r.get("age"), minAge));
            }
            //isNotNull非空
            predicates.add(b.isNotNull(r.get("id")));
            //isNull空
            predicates.add(b.isNull(r.get("nikeName")));
            return b.and(predicates.toArray(new Predicate[0]));
        });
    }

2、Sort排序查询

public void queryUserInfo(String userCode) {
    //DESC倒序,ASC升序,id表示需要排序的字段
    Sort sort = Sort.by(Sort.Direction.ASC, "id");
    List<UserInfoEntity> userInfoList = multiLoanRepository.findAll((Specification<UserInfoEntity>) (r, q, b) -> {
        List<Predicate> predicates = new ArrayList<>();
        if (StringUtils.isNotBlank(userCode)) {
             //equal等于
             predicates.add(b.equal(r.get("userCode"), userCode));
        }
        return b.and(predicates.toArray(new Predicate[0]));
    }, sort);
}

3、分页+排序查询

public void queryUserInfo(QueryUserRequest request) {
    //排序
    Sort sort = Sort.by(Sort.Order.desc("id"));
    //构造分页请求参数,PageIndex当前页码,PageSiz每页大小
    PageRequest pageRequest = PageRequest.of(request.getPageIndex(), request.getPageSize(), sort);
    Page<UserInfoEntity> userInfoPage = envConfigureRepository.findAll((Specification<UserInfoEntity>) (r, q, b) -> {
        List<Predicate> predicates = new ArrayList<>();
        if (StringUtils.hasText(request.getDescription())) {
            predicates.add(b.equal(r.get("sex"), request.getSex()));
        }
        return b.and(predicates.toArray(new Predicate[0]));
    }, pageRequest);
    //获取总页数
    Integer totalPages = userInfoPage.getTotalPages();
    //获取数据总条数
    Long totalElements = userInfoPage.getTotalElements();
    //获取查询内容
    List<UserInfoEntity> = userInfoPage.getContent();
}

4、查询单条记录findOne

注意:使用findOne查询时必须确保该条件最多只能查询出一条记录,否则会报错。

public void queryUserInfo(String userCode) {
    Optional<UserInfoEntity> userInfoOptional = multiLoanRepository.findOne((Specification<UserInfoEntity>) (r, q, b) -> {
        List<Predicate> predicates = new ArrayList<>();
        if (StringUtils.isNotBlank(userCode)) {
             //equal等于
             predicates.add(b.equal(r.get("userCode"), userCode));
        }
        return b.and(predicates.toArray(new Predicate[0]));
    });
    //判断是否查询到数据
    if (userInfoOptional.isPresent()) {
        UserInfoEntity userInfoEntity = userInfoOptional.get();
    }
}

   这里只是介绍Spring Data Jpa中动态查询最基本的用法,还有一些比如or,join等就不在这里展示了。