封裝查詢代碼,使用Criteria封裝多個條件並返回Predicate判斷
Specification<TsUser> spec = new Specification<TsUser>() {
@Override
public Predicate toPredicate(Root<TsUser> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Criteria<TsUser> c = new Criteria<TsUser>();
c.add(Restrictions.like("userName", userSearch.getUserName()));
// UserSearch是前端封裝的查詢表單對象
c.add(Restrictions.between("createdAt", DateUtil.parse(costSearch.getDateFrom()), DateUtil.parse(costSearch.getDateTo())));
//區間查詢
c.add(Restrictions.like("tsUserreg.userAlias", userSearch.getUserAlias()));
//查詢其餘相關表字段
c.add(Restrictions.
eq
(
"status"
, userSearch.getStatus()));
// 精確查詢
return c.toPredicate(root, query, cb);
}
};
//再次簡化,原來Criteria封裝並無使用Root+CriteriaQuery+CriteriaBuilder,因此添加spec()函數生成Specification查詢條件
Criteria<TsUser> c = new Criteria<>();
c.add(Restrictions.like("userName", userSearch.getUserName()));
c.add(Restrictions.
like
(
"tsAccount.paymentAccountId"
, userSearch.getPaymentAccountId()));
c.add(Restrictions.eq("tsUserreg.roleIds", userSearch.getRole()));//實際上應該封裝find_in_set函數,暫時僅支持單一角色
Pageable pageable =
new
PageRequest(pager.getCurrentPage()-1, pager.getPageSize(), Direction.
DESC
,
"id"
);
Page<User> users = userService.userPage(c.spec(), pageable);
Restrictions.java片斷
public static SimpleExpression eq(String fieldName, Object value) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Operator.EQ);
}
public
static
BetweenExpression between(String fieldName, Object value, Object value2) {
if(StringUtils.isEmpty(value) && StringUtils.isEmpty(value2)) return null;
return new BetweenExpression(fieldName, value, value2);
}
AbstractExpression,計算查詢路徑(支持屬性嵌套,例如address.zipCode)
public abstract class AbstractExpression implements Criterion {
Path getExpression(Root<?> root, String fieldName) {
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);
}
return expression;
}
}
SimpleExpression,支持Equal、Like、LessThan等條件
public Predicate toPredicate(Root<?> root, CriteriaQuery<?> query,
CriteriaBuilder builder) {
Path expression = getExpression(root,
fieldName
);
switch
(
operator
) {
case EQ:
return builder.equal(expression, value);
case
LIKE
:
return builder.like((Expression<String>) expression, "%" + value + "%");
}
}
BetweenExpression,支持區間查詢
public Predicate toPredicate(Root<?> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
Path expression = getExpression(root, fieldName);
if(StringUtils.isEmpty(value)) {
return builder.greaterThanOrEqualTo(expression, (Comparable)value);
}else if(StringUtils.isEmpty(value2)) {
return builder.lessThanOrEqualTo(expression, (Comparable)value2);
}else {
return builder.between(expression, (Comparable)value, (Comparable)value2);
}
}
Criteria,
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();
// 沒有條件時至關於true
}
public void add(Criterion criterion){
if(criterion!=null){
criterions.add(criterion);
}
}
public Specification<T> spec() {
return new Specification<T>() {
public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return Criteria.this.toPredicate(root, query, cb);
}
};
}
}