IMO,您仍然需要编写像if(phone!=null&&name!=null) 这样的代码。但是您可以对代码进行转义,并编写一次。
首先,你应该知道Specification<T>很好地支持动态查询。下面贴上我的代码。
Specification<Goods> spec = new Specification<Goods>() {
@Override
public Predicate toPredicate(Root<Goods> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Predicate predicate = cb.conjunction();
if (goodsSearch.getGoodsClassId() != -1) {
predicate = cb.and(predicate, cb.equal(root.get("goodsClassId"), goodsSearch.getGoodsClassId()));
}
return query.where(predicate).getRestriction();
}
};
return goodsDao.findAll(spec, pageable);
好的,你可以用lambda代替匿名类。然后你可以把Specification<T>转义,把if(phone!=null&&name!=null)这样的代码放进去。
示例代码:
public Specification<T> term(String fieldName, Operator operator, Object value) {
return new Specification<T>() {
@Override
public Predicate toPredicate(Root<T> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder builder) {
if (value == null) {
return null;
}
Path expression = null;
// if a.b, then use join
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);
}
// the different operation
switch (operator) {
case EQ:
return builder.equal(expression, value);
case NE:
return builder.notEqual(expression, value);
case LT:
return builder.lessThan(expression, (Comparable) value);
case GT:
return builder.greaterThan(expression, (Comparable) value);
case LIKE:
return builder.like((Expression<String>) expression, "%" + value + "%");
case LTE:
return builder.lessThanOrEqualTo(expression, (Comparable) value);
case GTE:
return builder.greaterThanOrEqualTo(expression, (Comparable) value);
case BT:
List<Object> paramList = (List<Object>) value;
if (paramList.size() == 2) {
return builder.between(expression, (Comparable) paramList.get(0), (Comparable) paramList.get(1));
}
case IN:
return builder.in(expression).value(value);
default:
return null;
}
}
};
}
我没有在里面写示例代码if(phone!=null&&name!=null)。