最近使用spring data jpa做了两个项目,对于动态查询的不友好做了个类似hibernate的封装,记录也分享下
首先定义一个所有条件的容器,继承Specification
Java代码 
-
/**
-
* 定义一个查询条件容器
-
* @author lee
-
*
-
* @param <T>
-
*/
-
public class Criteria<T> implements Specification<T>{
-
private List<Criterion> criterions = new ArrayList<Criterion>();
-
public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query,
-
CriteriaBuilder builder) {
-
if (!criterions.isEmpty()) {
-
List<Predicate> predicates = new ArrayList<Predicate>();
-
for(Criterion c : criterions){
-
predicates.add(c.toPredicate(root, query,builder));
-
}
-
// 将所有条件用 and 联合起来
-
if (predicates.size() > 0) {
-
return builder.and(predicates.toArray(new Predicate[predicates.size()]));
-
}
-
}
-
return builder.conjunction();
-
}
-
/**
-
* 增加简单条件表达式
-
* @Methods Name add
-
* @Create In 2012-2-8 By lee
-
* @param expression0 void
-
*/
-
public void add(Criterion criterion){
-
if(criterion!=null){
-
criterions.add(criterion);
-
}
-
}
-
}
然后是各种条件组装类,我首先做了一个接口来包装各种条件
Java代码 
- /**
- * 条件接口
- * 用户提供条件表达式接口
- * @Class Name Criterion
- * @Author lee
- * @Create In 2012-2-8
- */
- public interface Criterion {
- public enum Operator {
- EQ, NE, LIKE, GT, LT, GTE, LTE, AND, OR
- }
- public Predicate toPredicate(Root<?> root, CriteriaQuery<?> query,
- CriteriaBuilder builder);
- }
然后是针对不同类型条件处理的实现
一个是简单比较类型的处理
Java代码 
-
/**
-
* 简单条件表达式
-
* @author lee
-
*
-
*/
-
public class SimpleExpression implements Criterion{
-
private String fieldName; //属性名
-
private Object value; //对应值
-
private Operator operator; //计算符
-
protected SimpleExpression(String fieldName, Object value, Operator operator) {
-
this.fieldName = fieldName;
-
this.value = value;
-
this.operator = operator;
-
}
-
public String getFieldName() {
-
return fieldName;
-
}
-
public Object getValue() {
-
return value;
-
}
-
public Operator getOperator() {
-
return operator;
-
}
-
@SuppressWarnings({ "rawtypes", "unchecked" })
-
public Predicate toPredicate(Root<?> root, CriteriaQuery<?> query,
-
CriteriaBuilder builder) {
-
Path expression = null;
-
if(fieldName.contains(".")){
-
String[] names = StringUtils.split(fieldName, ".");
-
expression = root.get(names[0]);
-
for (int i = 1; i < names.length; i++) {
-
expression = expression.get(names[i]);
-
}
-
}else{
-
expression = root.get(fieldName);
-
}
-
switch (operator) {
-
case EQ:
-
return builder.equal(expression, value);
-
case NE:
-
return builder.notEqual(expression, value);
-
case LIKE:
-
return builder.like((Expression<String>) expression, "%" + value + "%");
-
case LT:
-
return builder.lessThan(expression, (Comparable) value);
-
case GT:
-
return builder.greaterThan(expression, (Comparable) value);
-
case LTE:
-
return builder.lessThanOrEqualTo(expression, (Comparable) value);
-
case GTE:
-
return builder.greaterThanOrEqualTo(expression, (Comparable) value);
-
default:
-
return null;
-
}
-
}
-
}
一个逻辑条件计算实现
Java代码 
-
/**
-
* 逻辑条件表达式 用于复杂条件时使用,如但属性多对应值的OR查询等
-
* @author lee
-
*
-
*/
-
public class LogicalExpression implements Criterion {
-
private Criterion[] criterion; // 逻辑表达式中包含的表达式
-
private Operator operator; //计算符
-
public LogicalExpression(Criterion[] criterions, Operator operator) {
-
this.criterion = criterions;
-
this.operator = operator;
-
}
-
public Predicate toPredicate(Root<?> root, CriteriaQuery<?> query,
-
CriteriaBuilder builder) {
-
List<Predicate> predicates = new ArrayList<Predicate>();
-
for(int i=0;i<this.criterion.length;i++){
-
predicates.add(this.criterion[i].toPredicate(root, query, builder));
-
}
-
switch (operator) {
-
case OR:
-
return builder.or(predicates.toArray(new Predicate[predicates.size()]));
-
default:
-
return null;
-
}
-
}
-
}
添加一个组装工厂类
Java代码 
-
/**
-
* 条件构造器
-
* 用于创建条件表达式
-
* @Class Name Restrictions
-
* @Author lee
-
*/
-
public class Restrictions {
-
/**
-
* 等于
-
* @param fieldName
-
* @param value
-
* @param ignoreNull
-
* @return
-
*/
-
public static SimpleExpression eq(String fieldName, Object value, boolean ignoreNull) {
-
if(StringUtils.isEmpty(value))return null;
-
return new SimpleExpression (fieldName, value, Operator.EQ);
-
}
-
/**
-
* 不等于
-
* @param fieldName
-
* @param value
-
* @param ignoreNull
-
* @return
-
*/
-
public static SimpleExpression ne(String fieldName, Object value, boolean ignoreNull) {
-
if(StringUtils.isEmpty(value))return null;
-
return new SimpleExpression (fieldName, value, Operator.NE);
-
}
-
/**
-
* 模糊匹配
-
* @param fieldName
-
* @param value
-
* @param ignoreNull
-
* @return
-
*/
-
public static SimpleExpression like(String fieldName, String value, boolean ignoreNull) {
-
if(StringUtils.isEmpty(value))return null;
-
return new SimpleExpression (fieldName, value, Operator.LIKE);
-
}
-
/**
-
*
-
* @param fieldName
-
* @param value
-
* @param matchMode
-
* @param ignoreNull
-
* @return
-
*/
-
public static SimpleExpression like(String fieldName, String value,
-
MatchMode matchMode, boolean ignoreNull) {
-
if(StringUtils.isEmpty(value))return null;
-
return null;
-
}
-
/**
-
* 大于
-
* @param fieldName
-
* @param value
-
* @param ignoreNull
-
* @return
-
*/
-
public static SimpleExpression gt(String fieldName, Object value, boolean ignoreNull) {
-
if(StringUtils.isEmpty(value))return null;
-
return new SimpleExpression (fieldName, value, Operator.GT);
-
}
-
/**
-
* 小于
-
* @param fieldName
-
* @param value
-
* @param ignoreNull
-
* @return
-
*/
-
public static SimpleExpression lt(String fieldName, Object value, boolean ignoreNull) {
-
if(StringUtils.isEmpty(value))return null;
-
return new SimpleExpression (fieldName, value, Operator.LT);
-
}
-
/**
-
* 大于等于
-
* @param fieldName
-
* @param value
-
* @param ignoreNull
-
* @return
-
*/
-
public static SimpleExpression lte(String fieldName, Object value, boolean ignoreNull) {
-
if(StringUtils.isEmpty(value))return null;
-
return new SimpleExpression (fieldName, value, Operator.GTE);
-
}
-
/**
-
* 小于等于
-
* @param fieldName
-
* @param value
-
* @param ignoreNull
-
* @return
-
*/
-
public static SimpleExpression gte(String fieldName, Object value, boolean ignoreNull) {
-
if(StringUtils.isEmpty(value))return null;
-
return new SimpleExpression (fieldName, value, Operator.LTE);
-
}
-
/**
-
* 并且
-
* @param criterions
-
* @return
-
*/
-
public static LogicalExpression and(Criterion... criterions){
-
return new LogicalExpression(criterions, Operator.AND);
-
}
-
/**
-
* 或者
-
* @param criterions
-
* @return
-
*/
-
public static LogicalExpression or(Criterion... criterions){
-
return new LogicalExpression(criterions, Operator.OR);
-
}
-
/**
-
* 包含于
-
* @param fieldName
-
* @param value
-
* @return
-
*/
-
@SuppressWarnings("rawtypes")
-
public static LogicalExpression in(String fieldName, Collection value, boolean ignoreNull) {
-
if(ignoreNull&&(value==null||value.isEmpty())){
-
return null;
-
}
-
SimpleExpression[] ses = new SimpleExpression[value.size()];
-
int i=0;
-
for(Object obj : value){
-
ses[i]=new SimpleExpression(fieldName,obj,Operator.EQ);
-
i++;
-
}
-
return new LogicalExpression(ses,Operator.OR);
-
}
-
}
使用方法如下
Java代码 
- Criteria<Event> c = new Criteria<Event>();
- c.add(Restrictions.like("code", searchParam.getCode(), true));
- c.add(Restrictions.eq("level", searchParam.getLevel(), false));
- c.add(Restrictions.eq("mainStatus", searchParam.getMainStatus(), true));
- c.add(Restrictions.eq("flowStatus", searchParam.getFlowStatus(), true));
- c.add(Restrictions.eq("createUser.userName", searchParam.getCreateUser(), true));
- c.add(Restrictions.lte("submitTime", searchParam.getStartSubmitTime(), true));
- c.add(Restrictions.gte("submitTime", searchParam.getEndSubmitTime(), true));
- c.add(Restrictions.eq("needFollow", searchParam.getIsfollow(), true));
- c.add(Restrictions.ne("flowStatus", CaseConstants.CASE_STATUS_DRAFT, true));
- c.add(Restrictions.in("solveTeam.code",teamCodes, true));
- eventDao.findAll(c);
其中eventDao为继承JpaSpecificationExecutor的接口类