引用maven配置
<!-- jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- MySQL数据库 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
jpa文档
中文文档:https://www.cntofu.com/book/88/index.html
官方文档:http://jvm123.com/doc/jpa/index.html
动态配置查询
- Repository方法继承JpaSpecificationExecutor方法通过Specification进行动态拼接查询语句
核心配置
/**
* 动态查询统一构造
* @param root 查询中的条件表达式
* @param criteriaQuery 条件查询设计器
* @param criteriaBuilder 条件查询构造器
* @return
*/
@Override
public Predicate toPredicate(Root<T> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicates = new ArrayList<>();
opers.forEach( filter -> {
// Path 继承了 Expression ;将属性名称转换为表达式.
Path expression=null;
//左链接查询
if(filter.getKey().contains(".")){
String[] split = filter.getKey().split("\\.");
expression = root.join(split[0], JoinType.LEFT).get(split[1]);
}else {
expression= root.get(filter.getKey());
}
switch (filter.getOperator()) {
case EQ:
predicates.add(criteriaBuilder.equal(expression, filter.getValue()));
break;
case NE:
predicates.add(criteriaBuilder.notEqual(expression, filter.getValue()));
break;
case LIKE:
predicates.add(criteriaBuilder.like(expression, "%" + filter.getValue() + "%"));
break;
case GT:
predicates.add(criteriaBuilder.greaterThan(expression, (Comparable) filter.getValue()));
break;
case LT:
predicates.add(criteriaBuilder.lessThan(expression, (Comparable) filter.getValue()));
break;
case GTE:
predicates.add(criteriaBuilder.greaterThanOrEqualTo(expression, (Comparable) filter.getValue()));
break;
case LTE:
predicates.add(criteriaBuilder.lessThanOrEqualTo(expression, (Comparable) filter.getValue()));
break;
case IN:
// 使用IN的查询,需要以数组为Value;
predicates.add(criteriaBuilder.isTrue(expression.in((Object[]) filter.getValue())));
break;
case BETWEENDATE:
// 使用IN的查询,需要以数组为Value;
predicates.add(criteriaBuilder.between(expression, (Date) ((List) filter.getValue()).get(0),
(Date) ((List) filter.getValue()).get(1)));
break;
case BETWEENLONG:
// 使用IN的查询,需要以数组为Value;
predicates.add(criteriaBuilder.between(expression, (Long) ((List) filter.getValue()).get(0),
(Long) ((List) filter.getValue()).get(1)));
break;
case ISNULL:
predicates.add(criteriaBuilder.isNull(expression));
break;
case ISNOTNULL:
predicates.add(criteriaBuilder.isNotNull(expression));
break;
}
});
// 将所有条件用 and 联合起来
if (predicates.size() > 0) {
return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
}
return criteriaBuilder.conjunction();
}
其他配置
1、枚举
public enum Operator {
EQ, NE, LIKE, GT, LT, GTE, LTE, IN,NOTIN,ISNULL, ISNOTNULL, BETWEENDATE, BETWEENLONG
}
2、构造配置
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SpecificationOperator {
private String key;
private Operator operator;
private Object value;
}
3、生成Specification
public class BaseSearchDto {
/**
* 默认只查询正常显示的
*/
private Integer existType=0;
private Date createdTime ;
/**
* 修改时间
*/
private Date updatedTime ;
/**
* 创建人
*/
private String createdUserId;
/**
* 修改人
*/
private String updatedUserId;
public List<SpecificationOperator> getSpecificationOperatorList() {
ArrayList<SpecificationOperator> specificationOperatorList = new ArrayList<>();
SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
specificationOperatorList.add(getSpecificationOperator("existType",Operator.EQ,existType));
if(!Strings.isBlank(updatedUserId)){
specificationOperatorList.add(getSpecificationOperator("updatedUserId",Operator.EQ,updatedUserId));
}
if(!Strings.isBlank(createdUserId)){
specificationOperatorList.add(getSpecificationOperator("createdUserId",Operator.EQ,createdUserId));
}
return specificationOperatorList;
}
/**
* 提供子类调用的方法(封装查询条件)
* @param key
* @param operator
* @param value
* @return
*/
protected static SpecificationOperator getSpecificationOperator(String key, Operator operator, Object value){
SpecificationOperator specificationOperator = new SpecificationOperator(key,operator,value);
if(value instanceof List){
Object[] objects = ((List<?>) value).toArray(new Object[((List<?>) value).size()]);
specificationOperator.setValue(objects);
}
return specificationOperator;
}