使用了一段时间的Spring data jpa 的分页查询,觉得每次都要写大量的重复代码实在是没啥效率,就想能不能封装一下,于是我花了几个小时封装了一套生成查询条件的工具类,特此分享干货如下:
新建工具类:CriteriaBuilderUtils
代码如下:
import org.apache.commons.lang3.StringUtils;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @author yantz
* @version 1.0
* @since 2018/12/20
*/
public class CriteriaBuilderUtils {
private CriteriaBuilderUtils(){
}
private static final String SPERATOR = "_";
/**
* 拼接PredicateKey
* @param properties 属性字段名
* @param criteriaType 条件类型 取值参考CriteriaType 枚举
* @param columnType 字段类型 取值参考ColumnType 枚举
* @return
* @throws Exception
*/
public static String getPredicateKey(String properties,String criteriaType,String columnType) throws Exception {
if(StringUtils.isBlank(properties) || StringUtils.isBlank(criteriaType) || StringUtils.isBlank(columnType)){
throw new Exception("拼接PredicateKey失败,参数有空值");
}
return properties.concat(SPERATOR).concat(criteriaType).concat(SPERATOR).concat(columnType);
}
/**
* 获取Predicate 查询条件
* @param root Root
* @param criteriaQuery CriteriaQuery
* @param criteriaBuilder CriteriaBuilder
* @param objectMap 查询参数对象
* @return Predicate
*/
public static Predicate getPredicate(Root root, CriteriaQuery> criteriaQuery, CriteriaBuilder criteriaBuilder, Map objectMap){
List predicateList = new ArrayList<>();
objectMap.forEach((key,value) ->{
int indexOf = key.indexOf("_");
int lastIndexOf = key.lastIndexOf("_");
int length = key.length();
String column = key.substring(0, indexOf);
String type = key.substring(indexOf+1,lastIndexOf);
String columnType = key.substring(lastIndexOf +1, length);
if(StringUtils.equals(type.toLowerCase(),CriteriaType.LIKE.getValue()) && value != null){
predicateList.add(criteriaBuilder.like(root.get(column).as(getColumnTypeClass(columnType)), StringUtilsExt.getLikeValue(value.toString())));
}
if(StringUtils.equals(type.toLowerCase(),CriteriaType.EQUAL.getValue()) && value != null){
predicateList.add(criteriaBuilder.equal(root.get(column).as(getColumnTypeClass(columnType)), value));
}
if(StringUtils.equals(type.toLowerCase(),CriteriaType.GREATER_THAN.getValue()) && value != null){
predicateList.add(criteriaBuilder.greaterThan(root.get(column).as(getColumnTypeClass(columnType)), String.valueOf(value)));
}
if(StringUtils.equals(type.toLowerCase(),CriteriaType.LESS_THAN.getValue()) && value != null){
predicateList.add(criteriaBuilder.lessThan(root.get(column).as(getColumnTypeClass(columnType)), String.valueOf(value)));
}
});
Predicate[] predicates = new Predicate[predicateList.size()];
criteriaQuery.where(predicateList.toArray(predicates));
return criteriaBuilder.and(predicateList.toArray(predicates));
}
/**
* 获取字段类型,用于Root强转
* @param columnType
* @return
*/
private static Class getColumnTypeClass(String columnType){
Class tClass = null;
switch (columnType.toLowerCase()){
case "string":
tClass = String.class;
break;
case "integer":
tClass = Integer.class;
break;
case "date":
tClass = Date.class;
break;
}
return tClass;
}
/**
* 查询条件类型
*/
public enum CriteriaType{
EQUAL("equal"),
LIKE("like"),
GREATER_THAN("greaterThan"),
LESS_THAN("lessThan");
private String value;
CriteriaType(String value){
this.value = value;
}
public String getValue(){
return this.value;
}
}
/**
* 字段类型
*/
public enum ColumnType{
STRING("string"),
INTEGER("integer"),
DATE("date");
private String value;
ColumnType(String value){
this.value = value;
}
public String getValue(){
return this.value;
}
}
}
具体使用如下:
public Page getBdmDictTypes(BdmDictTypeVo bdmDictTypeVo){
Page all = bdmDictTypeRepository.findAll(new Specification() {
@Override
public Predicate toPredicate(Root root, CriteriaQuery> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//拼装参数的Map
Map columnMaps = new HashMap<>();
try {
columnMaps.put(CriteriaBuilderUtils.getPredicateKey("dictTypeCode",CriteriaBuilderUtils.CriteriaType.EQUAL.getValue(),
CriteriaBuilderUtils.ColumnType.STRING.getValue()),bdmDictTypeVo.getDictTypeCode());
columnMaps.put(CriteriaBuilderUtils.getPredicateKey("deletedFlag",CriteriaBuilderUtils.CriteriaType.EQUAL.getValue(),
CriteriaBuilderUtils.ColumnType.INTEGER.getValue()),bdmDictTypeVo.getDeletedFlag());
columnMaps.put(CriteriaBuilderUtils.getPredicateKey("dictTypeName",CriteriaBuilderUtils.CriteriaType.LIKE.getValue(),
CriteriaBuilderUtils.ColumnType.STRING.getValue()),bdmDictTypeVo.getDictTypeName());
} catch (Exception e) {
LOGGER.error("===== getBdmDictCodePage toPredicate is error",e);
}
return CriteriaBuilderUtils.getPredicate(root, criteriaQuery, criteriaBuilder, columnMaps);
}
}, PageableUtils.getSortPageable(bdmDictTypeVo.getPage(),bdmDictTypeVo.getRowsPerPage(),bdmDictTypeVo.getSortBy(),bdmDictTypeVo.isDescending()));
return all;
}
封装的查询条件不全,只是将目前使用到的进行了封装,如果大佬们有更好的方法,欢迎留言分享,谢谢!