最近一段时间在使用SpringDataJPA框架进行开发,对于动态查询总结一二
目录
1.组装多条件查询条件
return new Specification<ReceivableEntity>() {
@Override
public Predicate toPredicate(Root<ReceivableEntity> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
// 多条件查询
}
1)find_in_set函数构造使用
Expression<String> findInSetFun = criteriaBuilder.function("FIND_IN_SET", String.class, criteriaBuilder.literal(receivables.getLoginItcode()), root.get("assistantSalesmanItcode"));
//设置条件 只要返回值 >0 则说明该参数存在于目标字符串中
predicatesOr.add(criteriaBuilder.notEqual(findInSetFun,"0"));
2)equal 方法使用
// 按照一级业务类型查询
if (StringUtils.isNotBlank(receivables.getLevel1BusinessTypeCode())) {
predicatesAnd.add(criteriaBuilder.equal(root.get("level1BusinessTypeCode"),receivables.getLevel1BusinessTypeCode()));
}
3)notEqual方法使用
if (StringUtils.isNotBlank(projectInfoDto.getLoginItcode())) {
predicatesOr.add(criteriaBuilder.equal(root.get("mainSalesmanItcode"), projectInfoDto.getLoginItcode()));
Expression<String> findInSetFun = criteriaBuilder.function("FIND_IN_SET", String.class, criteriaBuilder.literal(projectInfoDto.getLoginName()+"/"+projectInfoDto.getLoginItcode()), root.get("assistantSalesmanItcode"));
//设置条件 只要返回值 >0 则说明该参数存在于目标字符串中
predicatesOr.add(criteriaBuilder.notEqual(findInSetFun,"0"));
}
4)like方法的使用
// 按照项目编号模糊查询
if (StringUtils.isNotBlank(projectInfoDto.getProjectCode())) {
predicatesAnd.add(criteriaBuilder.like(root.get("projectCode"),"%"+projectInfoDto.getProjectCode()+"%"));
}
// 按照项目名称模糊查询
if (StringUtils.isNotBlank(projectInfoDto.getProjectName())) {
predicatesAnd.add(criteriaBuilder.like(root.get("projectName"),"%"+projectInfoDto.getProjectName()+"%"));
}
5)in方法的使用
CriteriaBuilder.In<String> in = criteriaBuilder.in(root.get("businessStatusCode"));
for (String id : projectInfoDto.getBusinessStatusCodeList()) {
in.value(id);
}
predicatesAnd.add(in);
6)多条件排序
// jpa中动态sql将汉字按照字母顺序排序
List<Predicate> list = new ArrayList<>();
Expression<String> convertRealnameFunction = criteriaBuilder.function("convert", String.class, root.get("projectName"));
Order nameAsc = criteriaBuilder.asc(convertRealnameFunction);
Order period = criteriaBuilder.asc(root.get("period"));
// 按照项目名称以及期次排序
query.orderBy(nameAsc,period);
Predicate predicateOrder = criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
7)notIn方法的使用
// 项目列表默认不查询财务结项和售前结项
String[] code = {"7","8"};
List<String> businessStatusCodes = Arrays.asList(code);
if (Objects.nonNull(businessStatusCodes) && !businessStatusCodes.isEmpty()) {
CriteriaBuilder.In<String> in = criteriaBuilder.in(root.get("businessStatusCode"));
for (String id : businessStatusCodes) {
in.value(id);
}
predicatesAnd.add(in.not());
}
8)区间查询
// 按照收款金额区间查询
if (StringUtils.isNotBlank(projectInfoDto.getMinProjectContractAmount()) && StringUtils.isBlank(projectInfoDto.getMaxProjectContractAmount())) {
predicatesAnd.add(criteriaBuilder.greaterThan(root.get("projectContractAmount"), Double.parseDouble(projectInfoDto.getMinProjectContractAmount())*10000));
}else if (StringUtils.isNotBlank(projectInfoDto.getMinProjectContractAmount()) && StringUtils.isNotBlank(projectInfoDto.getMaxProjectContractAmount())) {
predicatesAnd.add(criteriaBuilder.between(root.get("projectContractAmount"), Double.parseDouble(projectInfoDto.getMinProjectContractAmount())*10000, Double.parseDouble(projectInfoDto.getMaxProjectContractAmount())*10000));
}else if (StringUtils.isBlank(projectInfoDto.getMinProjectContractAmount()) && StringUtils.isNotBlank(projectInfoDto.getMaxProjectContractAmount())){
predicatesAnd.add(criteriaBuilder.lessThan(root.get("projectContractAmount"),Double.parseDouble(projectInfoDto.getMaxProjectContractAmount())*10000));
}
9)查询条件and、or以及排序的组合
//将集合转化为CriteriaBuilder所需要的Predicate[]
Predicate predicateOR = criteriaBuilder.or(predicatesOr.toArray(new Predicate[predicatesOr.size()]));
Predicate predicateAnd = criteriaBuilder.and(predicatesAnd.toArray(new Predicate[predicatesAnd.size()]));
if (predicatesAnd.isEmpty()) {
return query.where(predicateOR,predicateOrder).getRestriction();
} else {
return query.where(predicateOR,predicateAnd,predicateOrder).getRestriction();
}