|
@@ -0,0 +1,213 @@
|
|
|
+/*
|
|
|
+ * *************************************************
|
|
|
+ * Copyright (c) 2018 QMTH. All Rights Reserved.
|
|
|
+ * Created by Deason on 2018-10-23 15:43:17.
|
|
|
+ * *************************************************
|
|
|
+ */
|
|
|
+
|
|
|
+package cn.com.qmth.examcloud.core.print.common.jpa;
|
|
|
+
|
|
|
+import org.springframework.data.jpa.domain.Specification;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Collection;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author: fengdesheng
|
|
|
+ * @since: 2018/10/23
|
|
|
+ */
|
|
|
+public class SearchBuilder {
|
|
|
+ private List<Searcher> searchers;
|
|
|
+
|
|
|
+ public SearchBuilder() {
|
|
|
+ searchers = new ArrayList<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<Searcher> build() {
|
|
|
+ return searchers;
|
|
|
+ }
|
|
|
+
|
|
|
+ public <T> SearchBuilder eq(String fieldName, T value) {
|
|
|
+ searchers.add(new Searcher(fieldName, value, Op.EQ));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <T> Specification EQ(String fieldName, T value) {
|
|
|
+ return (root, query, cb) -> cb.equal(root.get(fieldName), value);
|
|
|
+ }
|
|
|
+
|
|
|
+ public <T> SearchBuilder notEq(String fieldName, T value) {
|
|
|
+ searchers.add(new Searcher(fieldName, value, Op.NOT_EQ));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <T> Specification NOT_EQ(String fieldName, T value) {
|
|
|
+ return (root, query, cb) -> cb.notEqual(root.get(fieldName), value);
|
|
|
+ }
|
|
|
+
|
|
|
+ public <T> SearchBuilder gt(String fieldName, T value) {
|
|
|
+ searchers.add(new Searcher(fieldName, value, Op.GT));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <T> Specification GT(String fieldName, T value) {
|
|
|
+ return (root, query, cb) -> cb.greaterThan(root.get(fieldName), (Comparable) value);
|
|
|
+ }
|
|
|
+
|
|
|
+ public <T> SearchBuilder gte(String fieldName, T value) {
|
|
|
+ searchers.add(new Searcher(fieldName, value, Op.GTE));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <T> Specification GTE(String fieldName, T value) {
|
|
|
+ return (root, query, cb) -> cb.greaterThanOrEqualTo(root.get(fieldName), (Comparable) value);
|
|
|
+ }
|
|
|
+
|
|
|
+ public <T> SearchBuilder lt(String fieldName, T value) {
|
|
|
+ searchers.add(new Searcher(fieldName, value, Op.LT));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <T> Specification LT(String fieldName, T value) {
|
|
|
+ return (root, query, cb) -> cb.lessThan(root.get(fieldName), (Comparable) value);
|
|
|
+ }
|
|
|
+
|
|
|
+ public <T> SearchBuilder lte(String fieldName, T value) {
|
|
|
+ searchers.add(new Searcher(fieldName, value, Op.LTE));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <T> Specification LTE(String fieldName, T value) {
|
|
|
+ return (root, query, cb) -> cb.lessThanOrEqualTo(root.get(fieldName), (Comparable) value);
|
|
|
+ }
|
|
|
+
|
|
|
+ public <T> SearchBuilder like(String fieldName, T value) {
|
|
|
+ searchers.add(new Searcher(fieldName, value, Op.LIKE));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <T> Specification LIKE(String fieldName, T value) {
|
|
|
+ return (root, query, cb) -> cb.like(root.get(fieldName), "%" + value + "%");
|
|
|
+ }
|
|
|
+
|
|
|
+ public <T> SearchBuilder leftLike(String fieldName, T value) {
|
|
|
+ searchers.add(new Searcher(fieldName, value, Op.L_LIKE));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <T> Specification L_LIKE(String fieldName, T value) {
|
|
|
+ return (root, query, cb) -> cb.like(root.get(fieldName), "%" + value);
|
|
|
+ }
|
|
|
+
|
|
|
+ public <T> SearchBuilder rightLike(String fieldName, T value) {
|
|
|
+ searchers.add(new Searcher(fieldName, value, Op.R_LIKE));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <T> Specification R_LIKE(String fieldName, T value) {
|
|
|
+ return (root, query, cb) -> cb.like(root.get(fieldName), value + "%");
|
|
|
+ }
|
|
|
+
|
|
|
+ public SearchBuilder in(String fieldName, Collection<?> values) {
|
|
|
+ if (values == null || values.size() == 0) {
|
|
|
+ throw new IllegalArgumentException("In Values must be not empty.");
|
|
|
+ }
|
|
|
+ if (values.size() == 1) {
|
|
|
+ searchers.add(new Searcher(fieldName, values.iterator().next(), Op.EQ));
|
|
|
+ } else {
|
|
|
+ searchers.add(new Searcher(fieldName, values.toArray(), Op.IN));
|
|
|
+ }
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static Specification IN(String fieldName, Collection<?> values) {
|
|
|
+ if (values == null || values.size() == 0) {
|
|
|
+ throw new IllegalArgumentException("In Values must be not empty.");
|
|
|
+ }
|
|
|
+ if (values.size() == 1) {
|
|
|
+ return (root, query, cb) -> cb.equal(root.get(fieldName), values.iterator().next());
|
|
|
+ }
|
|
|
+ return (root, query, cb) -> root.get(fieldName).in(values);
|
|
|
+ }
|
|
|
+
|
|
|
+ public SearchBuilder notIn(String fieldName, Collection<?> values) {
|
|
|
+ if (values == null || values.size() == 0) {
|
|
|
+ throw new IllegalArgumentException("In Values must be not empty.");
|
|
|
+ }
|
|
|
+ if (values.size() == 1) {
|
|
|
+ searchers.add(new Searcher(fieldName, values.iterator().next(), Op.NOT_EQ));
|
|
|
+ } else {
|
|
|
+ searchers.add(new Searcher(fieldName, values.toArray(), Op.NOT_IN));
|
|
|
+ }
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static Specification NOT_IN(String fieldName, Collection<?> values) {
|
|
|
+ if (values == null || values.size() == 0) {
|
|
|
+ throw new IllegalArgumentException("In Values must be not empty.");
|
|
|
+ }
|
|
|
+ if (values.size() == 1) {
|
|
|
+ return (root, query, cb) -> cb.notEqual(root.get(fieldName), values.iterator().next());
|
|
|
+ }
|
|
|
+ return (root, query, cb) -> root.get(fieldName).in(values).not();
|
|
|
+ }
|
|
|
+
|
|
|
+ public SearchBuilder isNull(String fieldName) {
|
|
|
+ searchers.add(new Searcher(fieldName, null, Op.IS_NULL));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static Specification IS_NULL(String fieldName) {
|
|
|
+ return (root, query, cb) -> cb.isNull(root.get(fieldName));
|
|
|
+ }
|
|
|
+
|
|
|
+ public SearchBuilder notNull(String fieldName) {
|
|
|
+ searchers.add(new Searcher(fieldName, null, Op.NOT_NULL));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static Specification NOT_NULL(String fieldName) {
|
|
|
+ return (root, query, cb) -> cb.isNotNull(root.get(fieldName));
|
|
|
+ }
|
|
|
+
|
|
|
+ public static class Searcher<T> {
|
|
|
+ /**
|
|
|
+ * 属性名
|
|
|
+ */
|
|
|
+ private String fieldName;
|
|
|
+ /**
|
|
|
+ * 属性值
|
|
|
+ */
|
|
|
+ private T value;
|
|
|
+ /**
|
|
|
+ * 操作的表达式
|
|
|
+ */
|
|
|
+ private Op op;
|
|
|
+
|
|
|
+ private Searcher(String fieldName, T value, Op op) {
|
|
|
+ if (fieldName == null || "".equals(fieldName.trim())) {
|
|
|
+ throw new IllegalArgumentException("FieldName must be not empty.");
|
|
|
+ }
|
|
|
+ if (op == null) {
|
|
|
+ throw new IllegalArgumentException("Operator must be not empty.");
|
|
|
+ }
|
|
|
+ this.fieldName = fieldName.trim();
|
|
|
+ this.value = value;
|
|
|
+ this.op = op;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getFieldName() {
|
|
|
+ return fieldName;
|
|
|
+ }
|
|
|
+
|
|
|
+ public T getValue() {
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Op getOp() {
|
|
|
+ return op;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|