This commit is contained in:
@@ -5,9 +5,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.source;
|
package org.redkale.source;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
|
||||||
import static java.lang.annotation.ElementType.FIELD;
|
import static java.lang.annotation.ElementType.FIELD;
|
||||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -46,4 +46,11 @@ public @interface FilterColumn {
|
|||||||
*/
|
*/
|
||||||
FilterExpress express() default FilterExpress.EQUAL;
|
FilterExpress express() default FilterExpress.EQUAL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当标记的字段类型是数组/Collection类型且express不是IN/NOTIN时,则构建过滤条件时会遍历字段值的元素来循环构建表达式,元素之间的关系是AND或OR由该值来确定
|
||||||
|
*
|
||||||
|
* @return 数组元素间的表达式是否AND关系
|
||||||
|
*/
|
||||||
|
boolean itemand() default true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,15 +5,18 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.source;
|
package org.redkale.source;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.Serializable;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.atomic.*;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.function.*;
|
import java.util.function.*;
|
||||||
import org.redkale.util.*;
|
import static org.redkale.source.FilterExpress.EQUAL;
|
||||||
|
import org.redkale.util.Attribute;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* <p> 详情见: http://www.redkale.org
|
* <p>
|
||||||
|
* 详情见: http://www.redkale.org
|
||||||
|
*
|
||||||
* @author zhangjx
|
* @author zhangjx
|
||||||
*/
|
*/
|
||||||
public class FilterJoinNode extends FilterNode {
|
public class FilterJoinNode extends FilterNode {
|
||||||
@@ -27,41 +30,55 @@ public class FilterJoinNode extends FilterNode {
|
|||||||
public FilterJoinNode() {
|
public FilterJoinNode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected FilterJoinNode(Class joinClass, String[] joinColumns, String column, Serializable value) {
|
protected FilterJoinNode(Class joinClass, String[] joinColumns, String column, FilterExpress express, boolean itemand, Serializable value) {
|
||||||
this(joinClass, joinColumns, column, null, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected FilterJoinNode(Class joinClass, String[] joinColumns, String column, FilterExpress express, Serializable value) {
|
|
||||||
Objects.requireNonNull(joinClass);
|
Objects.requireNonNull(joinClass);
|
||||||
Objects.requireNonNull(joinColumns);
|
Objects.requireNonNull(joinColumns);
|
||||||
|
if (express == null && value != null) {
|
||||||
|
if (value instanceof Range) {
|
||||||
|
express = FilterExpress.BETWEEN;
|
||||||
|
} else if (value instanceof Collection) {
|
||||||
|
express = FilterExpress.IN;
|
||||||
|
} else if (value.getClass().isArray()) {
|
||||||
|
express = FilterExpress.IN;
|
||||||
|
}
|
||||||
|
}
|
||||||
this.joinClass = joinClass;
|
this.joinClass = joinClass;
|
||||||
this.joinColumns = joinColumns;
|
this.joinColumns = joinColumns;
|
||||||
this.column = column;
|
this.column = column;
|
||||||
this.express = express;
|
this.express = express == null ? EQUAL : express;
|
||||||
|
this.itemand = itemand;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected FilterJoinNode(FilterJoinNode node) {
|
protected FilterJoinNode(FilterJoinNode node) {
|
||||||
this(node.joinClass, node.joinColumns, node.column, node.express, node.value);
|
this(node.joinClass, node.joinColumns, node.column, node.express, node.itemand, node.value);
|
||||||
this.joinEntity = node.joinEntity;
|
this.joinEntity = node.joinEntity;
|
||||||
this.or = node.or;
|
this.or = node.or;
|
||||||
this.nodes = node.nodes;
|
this.nodes = node.nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FilterJoinNode create(Class joinClass, String joinColumn, String column, Serializable value) {
|
public static FilterJoinNode create(Class joinClass, String joinColumn, String column, Serializable value) {
|
||||||
return new FilterJoinNode(joinClass, new String[]{joinColumn}, column, value);
|
return create(joinClass, new String[]{joinColumn}, column, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FilterJoinNode create(Class joinClass, String joinColumn, String column, FilterExpress express, Serializable value) {
|
public static FilterJoinNode create(Class joinClass, String joinColumn, String column, FilterExpress express, Serializable value) {
|
||||||
return new FilterJoinNode(joinClass, new String[]{joinColumn}, column, express, value);
|
return create(joinClass, new String[]{joinColumn}, column, express, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FilterJoinNode create(Class joinClass, String joinColumn, String column, FilterExpress express, boolean itemand, Serializable value) {
|
||||||
|
return create(joinClass, new String[]{joinColumn}, column, express, itemand, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FilterJoinNode create(Class joinClass, String[] joinColumns, String column, Serializable value) {
|
public static FilterJoinNode create(Class joinClass, String[] joinColumns, String column, Serializable value) {
|
||||||
return new FilterJoinNode(joinClass, joinColumns, column, value);
|
return create(joinClass, joinColumns, column, null, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FilterJoinNode create(Class joinClass, String[] joinColumns, String column, FilterExpress express, Serializable value) {
|
public static FilterJoinNode create(Class joinClass, String[] joinColumns, String column, FilterExpress express, Serializable value) {
|
||||||
return new FilterJoinNode(joinClass, joinColumns, column, express, value);
|
return create(joinClass, joinColumns, column, express, true, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FilterJoinNode create(Class joinClass, String[] joinColumns, String column, FilterExpress express, boolean itemand, Serializable value) {
|
||||||
|
return new FilterJoinNode(joinClass, joinColumns, column, express, itemand, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -87,6 +104,7 @@ public class FilterJoinNode extends FilterNode {
|
|||||||
this.nodes = new FilterNode[]{new FilterJoinNode(node), node};
|
this.nodes = new FilterNode[]{new FilterJoinNode(node), node};
|
||||||
this.column = null;
|
this.column = null;
|
||||||
this.express = null;
|
this.express = null;
|
||||||
|
this.itemand = true;
|
||||||
this.value = null;
|
this.value = null;
|
||||||
this.joinClass = null;
|
this.joinClass = null;
|
||||||
this.joinEntity = null;
|
this.joinEntity = null;
|
||||||
@@ -260,7 +278,7 @@ public class FilterJoinNode extends FilterNode {
|
|||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
String[] joinColumns = node.joinColumns;
|
String[] joinColumns = node.joinColumns;
|
||||||
sb.append(" INNER JOIN ").append(node.joinEntity.getTable()).append(" ").append(joinTabalis.get(node.joinClass))
|
sb.append(" INNER JOIN ").append(node.joinEntity.getTable()).append(" ").append(joinTabalis.get(node.joinClass))
|
||||||
.append(" ON ").append(info.getSQLColumn("a", joinColumns[0])).append(" = ").append(node.joinEntity.getSQLColumn(joinTabalis.get(node.joinClass), joinColumns[0]));
|
.append(" ON ").append(info.getSQLColumn("a", joinColumns[0])).append(" = ").append(node.joinEntity.getSQLColumn(joinTabalis.get(node.joinClass), joinColumns[0]));
|
||||||
for (int i = 1; i < joinColumns.length; i++) {
|
for (int i = 1; i < joinColumns.length; i++) {
|
||||||
sb.append(" AND ").append(info.getSQLColumn("a", joinColumns[i])).append(" = ").append(node.joinEntity.getSQLColumn(joinTabalis.get(node.joinClass), joinColumns[i]));
|
sb.append(" AND ").append(info.getSQLColumn("a", joinColumns[i])).append(" = ").append(node.joinEntity.getSQLColumn(joinTabalis.get(node.joinClass), joinColumns[i]));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ public class FilterNode {
|
|||||||
|
|
||||||
protected Serializable value;
|
protected Serializable value;
|
||||||
|
|
||||||
|
protected boolean itemand;
|
||||||
|
|
||||||
//----------------------------------------------
|
//----------------------------------------------
|
||||||
protected boolean or;
|
protected boolean or;
|
||||||
|
|
||||||
@@ -36,21 +38,40 @@ public class FilterNode {
|
|||||||
public FilterNode() {
|
public FilterNode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected FilterNode(String col, FilterExpress exp, Serializable val) {
|
protected FilterNode(String col, FilterExpress exp, boolean itemand, Serializable val) {
|
||||||
Objects.requireNonNull(col);
|
Objects.requireNonNull(col);
|
||||||
if (exp == null) {
|
if (exp == null) {
|
||||||
if (val instanceof Range) {
|
if (val instanceof Range) {
|
||||||
exp = FilterExpress.BETWEEN;
|
exp = FilterExpress.BETWEEN;
|
||||||
} else if (val instanceof Collection) {
|
} else if (val instanceof Collection) {
|
||||||
exp = FilterExpress.IN;
|
if (!((Collection) val).isEmpty()) {
|
||||||
|
Object subval = null;
|
||||||
|
for (Object obj : (Collection) val) { //取第一个值
|
||||||
|
subval = obj;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (subval instanceof Range) {
|
||||||
|
exp = FilterExpress.BETWEEN;
|
||||||
|
} else if (subval instanceof Collection) {
|
||||||
|
exp = FilterExpress.IN;
|
||||||
|
} else if (subval != null && val.getClass().isArray()) {
|
||||||
|
exp = FilterExpress.IN;
|
||||||
|
}
|
||||||
|
} else { //空集合
|
||||||
|
exp = FilterExpress.IN;
|
||||||
|
}
|
||||||
} else if (val != null && val.getClass().isArray()) {
|
} else if (val != null && val.getClass().isArray()) {
|
||||||
exp = FilterExpress.IN;
|
Class comp = val.getClass().getComponentType();
|
||||||
} else {
|
if (Range.class.isAssignableFrom(comp)) {
|
||||||
exp = FilterExpress.EQUAL;
|
exp = FilterExpress.BETWEEN;
|
||||||
|
} else if (comp.isArray() || Collection.class.isAssignableFrom(comp)) {
|
||||||
|
exp = FilterExpress.IN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.column = col;
|
this.column = col;
|
||||||
this.express = exp;
|
this.express = exp == null ? EQUAL : exp;
|
||||||
|
this.itemand = itemand;
|
||||||
this.value = val;
|
this.value = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +84,11 @@ public class FilterNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final FilterNode and(String column, FilterExpress express, Serializable value) {
|
public final FilterNode and(String column, FilterExpress express, Serializable value) {
|
||||||
return and(new FilterNode(column, express, value));
|
return and(column, express, true, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final FilterNode and(String column, FilterExpress express, boolean itemand, Serializable value) {
|
||||||
|
return and(new FilterNode(column, express, itemand, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public final FilterNode or(FilterNode node) {
|
public final FilterNode or(FilterNode node) {
|
||||||
@@ -75,7 +100,11 @@ public class FilterNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final FilterNode or(String column, FilterExpress express, Serializable value) {
|
public final FilterNode or(String column, FilterExpress express, Serializable value) {
|
||||||
return or(new FilterNode(column, express, value));
|
return or(column, express, true, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final FilterNode or(String column, FilterExpress express, boolean itemand, Serializable value) {
|
||||||
|
return or(new FilterNode(column, express, itemand, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected FilterNode any(FilterNode node, boolean signor) {
|
protected FilterNode any(FilterNode node, boolean signor) {
|
||||||
@@ -83,6 +112,7 @@ public class FilterNode {
|
|||||||
if (this.column == null) {
|
if (this.column == null) {
|
||||||
this.column = node.column;
|
this.column = node.column;
|
||||||
this.express = node.express;
|
this.express = node.express;
|
||||||
|
this.itemand = node.itemand;
|
||||||
this.value = node.value;
|
this.value = node.value;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -98,12 +128,13 @@ public class FilterNode {
|
|||||||
this.nodes = newsiblings;
|
this.nodes = newsiblings;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
FilterNode newnode = new FilterNode(this.column, this.express, this.value);
|
FilterNode newnode = new FilterNode(this.column, this.express, this.itemand, this.value);
|
||||||
newnode.or = this.or;
|
newnode.or = this.or;
|
||||||
newnode.nodes = this.nodes;
|
newnode.nodes = this.nodes;
|
||||||
this.nodes = new FilterNode[]{newnode, node};
|
this.nodes = new FilterNode[]{newnode, node};
|
||||||
this.column = null;
|
this.column = null;
|
||||||
this.express = null;
|
this.express = null;
|
||||||
|
this.itemand = true;
|
||||||
this.or = signor;
|
this.or = signor;
|
||||||
this.value = null;
|
this.value = null;
|
||||||
return this;
|
return this;
|
||||||
@@ -206,16 +237,81 @@ public class FilterNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static FilterNode create(String column, FilterExpress express, Serializable value) {
|
public static FilterNode create(String column, FilterExpress express, Serializable value) {
|
||||||
return new FilterNode(column, express, value);
|
return create(column, express, true, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FilterNode create(String column, FilterExpress express, boolean itemand, Serializable value) {
|
||||||
|
return new FilterNode(column, express, itemand, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean needSplit(final Object val0) {
|
||||||
|
return needSplit(express, val0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean needSplit(final FilterExpress express, final Object val0) {
|
||||||
|
boolean items = express != IN && express != NOTIN; //是否数组集合的表达式
|
||||||
|
if (!items) {
|
||||||
|
if (val0.getClass().isArray()) {
|
||||||
|
Class comp = val0.getClass().getComponentType();
|
||||||
|
if (!(comp.isPrimitive() || CharSequence.class.isAssignableFrom(comp) || Number.class.isAssignableFrom(comp))) {
|
||||||
|
items = true;
|
||||||
|
}
|
||||||
|
} else if (val0 instanceof Collection) {
|
||||||
|
for (Object fv : (Collection) val0) {
|
||||||
|
if (fv == null) continue;
|
||||||
|
Class comp = fv.getClass();
|
||||||
|
if (!(comp.isPrimitive() || CharSequence.class.isAssignableFrom(comp) || Number.class.isAssignableFrom(comp))) {
|
||||||
|
items = true;
|
||||||
|
}
|
||||||
|
break; //只需检测第一个值
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final <T> CharSequence createElementSQLExpress(final EntityInfo<T> info, String talis) {
|
protected final <T> CharSequence createElementSQLExpress(final EntityInfo<T> info, String talis) {
|
||||||
|
final Object val0 = getValue();
|
||||||
|
if (needSplit(val0)) {
|
||||||
|
if (val0 instanceof Collection) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
boolean more = ((Collection) val0).size() > 1;
|
||||||
|
if (more) sb.append('(');
|
||||||
|
for (Object fv : (Collection) val0) {
|
||||||
|
if (fv == null) continue;
|
||||||
|
CharSequence cs = createElementSQLExpress(info, talis, fv);
|
||||||
|
if (cs == null) continue;
|
||||||
|
if (sb.length() > 2) sb.append(itemand ? " AND " : " OR ");
|
||||||
|
sb.append(cs);
|
||||||
|
}
|
||||||
|
if (more) sb.append(')');
|
||||||
|
return sb.length() > 3 ? sb : null; //若sb的值只是(),则不过滤
|
||||||
|
} else if (val0.getClass().isArray()) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
Object[] fvs = (Object[]) val0;
|
||||||
|
boolean more = fvs.length > 1;
|
||||||
|
if (more) sb.append('(');
|
||||||
|
for (Object fv : fvs) {
|
||||||
|
if (fv == null) continue;
|
||||||
|
CharSequence cs = createElementSQLExpress(info, talis, fv);
|
||||||
|
if (cs == null) continue;
|
||||||
|
if (sb.length() > 2) sb.append(itemand ? " AND " : " OR ");
|
||||||
|
sb.append(cs);
|
||||||
|
}
|
||||||
|
if (more) sb.append(')');
|
||||||
|
return sb.length() > 3 ? sb : null; //若sb的值只是(),则不过滤
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return createElementSQLExpress(info, talis, val0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> CharSequence createElementSQLExpress(final EntityInfo<T> info, String talis, Object val0) {
|
||||||
if (column == null) return null;
|
if (column == null) return null;
|
||||||
if (talis == null) talis = "a";
|
if (talis == null) talis = "a";
|
||||||
if (express == ISNULL || express == ISNOTNULL) {
|
if (express == ISNULL || express == ISNOTNULL) {
|
||||||
return new StringBuilder().append(info.getSQLColumn(talis, column)).append(' ').append(express.value());
|
return new StringBuilder().append(info.getSQLColumn(talis, column)).append(' ').append(express.value());
|
||||||
}
|
}
|
||||||
Object val0 = getValue();
|
|
||||||
if (val0 == null) return null;
|
if (val0 == null) return null;
|
||||||
if (express == FV_MOD || express == FV_DIV) {
|
if (express == FV_MOD || express == FV_DIV) {
|
||||||
FilterValue fv = (FilterValue) val0;
|
FilterValue fv = (FilterValue) val0;
|
||||||
@@ -294,6 +390,81 @@ public class FilterNode {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected final <T> Predicate<T> createElementPredicate(final EntityCache<T> cache, final boolean join, final Attribute<T, Serializable> attr) {
|
protected final <T> Predicate<T> createElementPredicate(final EntityCache<T> cache, final boolean join, final Attribute<T, Serializable> attr) {
|
||||||
|
final Object val0 = getValue();
|
||||||
|
if (needSplit(val0)) {
|
||||||
|
if (val0 instanceof Collection) {
|
||||||
|
Predicate<T> filter = null;
|
||||||
|
for (Object fv : (Collection) val0) {
|
||||||
|
if (fv == null) continue;
|
||||||
|
Predicate<T> f = createElementPredicate(cache, join, attr, fv);
|
||||||
|
if (f == null) continue;
|
||||||
|
final Predicate<T> one = filter;
|
||||||
|
final Predicate<T> two = f;
|
||||||
|
filter = (filter == null) ? f : (!itemand ? new Predicate<T>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(T t) {
|
||||||
|
return one.test(t) || two.test(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "(" + one + " OR " + two + ")";
|
||||||
|
}
|
||||||
|
} : new Predicate<T>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(T t) {
|
||||||
|
return one.test(t) && two.test(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "(" + one + " AND " + two + ")";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return filter;
|
||||||
|
} else if (val0.getClass().isArray()) {
|
||||||
|
Predicate<T> filter = null;
|
||||||
|
for (Object fv : (Object[]) val0) {
|
||||||
|
if (fv == null) continue;
|
||||||
|
Predicate<T> f = createElementPredicate(cache, join, attr, fv);
|
||||||
|
if (f == null) continue;
|
||||||
|
final Predicate<T> one = filter;
|
||||||
|
final Predicate<T> two = f;
|
||||||
|
filter = (filter == null) ? f : (!itemand ? new Predicate<T>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(T t) {
|
||||||
|
return one.test(t) || two.test(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "(" + one + " OR " + two + ")";
|
||||||
|
}
|
||||||
|
} : new Predicate<T>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(T t) {
|
||||||
|
return one.test(t) && two.test(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "(" + one + " AND " + two + ")";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return createElementPredicate(cache, join, attr, val0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected final <T> Predicate<T> createElementPredicate(final EntityCache<T> cache, final boolean join, final Attribute<T, Serializable> attr, Object val0) {
|
||||||
if (attr == null) return null;
|
if (attr == null) return null;
|
||||||
final String field = join ? (cache.getType().getSimpleName() + "." + attr.field()) : attr.field();
|
final String field = join ? (cache.getType().getSimpleName() + "." + attr.field()) : attr.field();
|
||||||
if (express == ISNULL) return new Predicate<T>() {
|
if (express == ISNULL) return new Predicate<T>() {
|
||||||
@@ -321,7 +492,6 @@ public class FilterNode {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (attr == null) return null;
|
if (attr == null) return null;
|
||||||
Serializable val0 = getValue();
|
|
||||||
if (val0 == null) return null;
|
if (val0 == null) return null;
|
||||||
|
|
||||||
final Class atype = attr.type();
|
final Class atype = attr.type();
|
||||||
@@ -436,7 +606,7 @@ public class FilterNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final Serializable val = val0;
|
final Serializable val = (Serializable) val0;
|
||||||
switch (express) {
|
switch (express) {
|
||||||
case EQUAL:
|
case EQUAL:
|
||||||
return new Predicate<T>() {
|
return new Predicate<T>() {
|
||||||
@@ -1125,10 +1295,44 @@ public class FilterNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected final StringBuilder toElementString(final String prefix) {
|
protected final StringBuilder toElementString(final String prefix) {
|
||||||
|
Serializable val0 = getValue();
|
||||||
|
if (needSplit(val0)) {
|
||||||
|
if (val0 instanceof Collection) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
boolean more = ((Collection) val0).size() > 1;
|
||||||
|
if (more) sb.append('(');
|
||||||
|
for (Object fv : (Collection) val0) {
|
||||||
|
if (fv == null) continue;
|
||||||
|
CharSequence cs = toElementString(prefix, fv);
|
||||||
|
if (cs == null) continue;
|
||||||
|
if (sb.length() > 2) sb.append(itemand ? " AND " : " OR ");
|
||||||
|
sb.append(cs);
|
||||||
|
}
|
||||||
|
if (more) sb.append(')');
|
||||||
|
return sb.length() > 3 ? sb : null; //若sb的值只是(),则不过滤
|
||||||
|
} else if (val0.getClass().isArray()) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
Object[] fvs = (Object[]) val0;
|
||||||
|
boolean more = fvs.length > 1;
|
||||||
|
if (more) sb.append('(');
|
||||||
|
for (Object fv : fvs) {
|
||||||
|
if (fv == null) continue;
|
||||||
|
CharSequence cs = toElementString(prefix, fv);
|
||||||
|
if (cs == null) continue;
|
||||||
|
if (sb.length() > 2) sb.append(itemand ? " AND " : " OR ");
|
||||||
|
sb.append(cs);
|
||||||
|
}
|
||||||
|
if (more) sb.append(')');
|
||||||
|
return sb.length() > 3 ? sb : null; //若sb的值只是(),则不过滤
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return toElementString(prefix, val0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final StringBuilder toElementString(final String prefix, Object ev) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
if (column != null) {
|
if (column != null) {
|
||||||
String col = prefix == null ? column : (prefix + "." + column);
|
String col = prefix == null ? column : (prefix + "." + column);
|
||||||
Serializable ev = getValue();
|
|
||||||
if (express == ISNULL || express == ISNOTNULL) {
|
if (express == ISNULL || express == ISNOTNULL) {
|
||||||
sb.append(col).append(' ').append(express.value());
|
sb.append(col).append(' ').append(express.value());
|
||||||
} else if (ev != null) {
|
} else if (ev != null) {
|
||||||
@@ -1245,6 +1449,14 @@ public class FilterNode {
|
|||||||
this.express = express;
|
this.express = express;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final boolean isItemand() {
|
||||||
|
return itemand;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setItemand(boolean itemand) {
|
||||||
|
this.itemand = itemand;
|
||||||
|
}
|
||||||
|
|
||||||
public final FilterNode[] getNodes() {
|
public final FilterNode[] getNodes() {
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,13 +5,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.source;
|
package org.redkale.source;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import javax.persistence.*;
|
import javax.persistence.Transient;
|
||||||
import static org.redkale.source.FilterExpress.*;
|
import static org.redkale.source.FilterExpress.*;
|
||||||
import org.redkale.util.*;
|
import org.redkale.util.Attribute;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -19,8 +19,9 @@ import org.redkale.util.*;
|
|||||||
* 详情见: http://www.redkale.org
|
* 详情见: http://www.redkale.org
|
||||||
*
|
*
|
||||||
* @author zhangjx
|
* @author zhangjx
|
||||||
|
* @param <T> FilterBean泛型
|
||||||
*/
|
*/
|
||||||
public final class FilterNodeBean<T> implements Comparable<FilterNodeBean<T>> {
|
public final class FilterNodeBean<T extends FilterBean> implements Comparable<FilterNodeBean<T>> {
|
||||||
|
|
||||||
private static final ConcurrentHashMap<Class, FilterNodeBean> beanodes = new ConcurrentHashMap<>();
|
private static final ConcurrentHashMap<Class, FilterNodeBean> beanodes = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -30,6 +31,8 @@ public final class FilterNodeBean<T> implements Comparable<FilterNodeBean<T>> {
|
|||||||
|
|
||||||
private FilterExpress express;
|
private FilterExpress express;
|
||||||
|
|
||||||
|
private boolean itemand;
|
||||||
|
|
||||||
private boolean or;
|
private boolean or;
|
||||||
|
|
||||||
private FilterNodeBean[] nodeBeans;
|
private FilterNodeBean[] nodeBeans;
|
||||||
@@ -50,6 +53,7 @@ public final class FilterNodeBean<T> implements Comparable<FilterNodeBean<T>> {
|
|||||||
this.beanAttr = bean == null ? null : bean.beanAttr;
|
this.beanAttr = bean == null ? null : bean.beanAttr;
|
||||||
this.column = bean == null ? null : bean.column;
|
this.column = bean == null ? null : bean.column;
|
||||||
this.express = bean == null ? null : bean.express;
|
this.express = bean == null ? null : bean.express;
|
||||||
|
this.itemand = bean == null ? true : bean.itemand;
|
||||||
this.joinClass = bean == null ? null : bean.joinClass;
|
this.joinClass = bean == null ? null : bean.joinClass;
|
||||||
this.joinColumns = bean == null ? null : bean.joinColumns;
|
this.joinColumns = bean == null ? null : bean.joinColumns;
|
||||||
this.least = bean == null ? 1 : bean.least;
|
this.least = bean == null ? 1 : bean.least;
|
||||||
@@ -68,10 +72,12 @@ public final class FilterNodeBean<T> implements Comparable<FilterNodeBean<T>> {
|
|||||||
this.column = (filterCol != null && !filterCol.name().isEmpty()) ? filterCol.name() : attr.field();
|
this.column = (filterCol != null && !filterCol.name().isEmpty()) ? filterCol.name() : attr.field();
|
||||||
|
|
||||||
FilterExpress exp = filterCol == null ? null : filterCol.express();
|
FilterExpress exp = filterCol == null ? null : filterCol.express();
|
||||||
if (type.isArray() || Collection.class.isAssignableFrom(type)) {
|
if ((exp == null || exp == EQUAL) && (type.isArray() || Collection.class.isAssignableFrom(type))) {
|
||||||
if (Range.class.isAssignableFrom(type.getComponentType())) {
|
if (Range.class.isAssignableFrom(type.getComponentType())) {
|
||||||
if (AND != exp) exp = OR;
|
if (AND != exp) exp = OR;
|
||||||
} else if (NOTIN != exp) exp = IN;
|
} else if (NOTIN != exp) {
|
||||||
|
exp = IN;
|
||||||
|
}
|
||||||
} else if (Range.class.isAssignableFrom(type)) {
|
} else if (Range.class.isAssignableFrom(type)) {
|
||||||
if (NOTBETWEEN != exp) exp = BETWEEN;
|
if (NOTBETWEEN != exp) exp = BETWEEN;
|
||||||
}
|
}
|
||||||
@@ -97,6 +103,7 @@ public final class FilterNodeBean<T> implements Comparable<FilterNodeBean<T>> {
|
|||||||
this.beanAttr = node.beanAttr;
|
this.beanAttr = node.beanAttr;
|
||||||
this.column = node.column;
|
this.column = node.column;
|
||||||
this.express = node.express;
|
this.express = node.express;
|
||||||
|
this.itemand = node.itemand;
|
||||||
this.joinClass = node.joinClass;
|
this.joinClass = node.joinClass;
|
||||||
this.joinColumns = node.joinColumns;
|
this.joinColumns = node.joinColumns;
|
||||||
this.least = node.least;
|
this.least = node.least;
|
||||||
@@ -133,16 +140,16 @@ public final class FilterNodeBean<T> implements Comparable<FilterNodeBean<T>> {
|
|||||||
final Serializable val = beanAttr.get(bean);
|
final Serializable val = beanAttr.get(bean);
|
||||||
if (column != null && val != null) {
|
if (column != null && val != null) {
|
||||||
boolean skip = false;
|
boolean skip = false;
|
||||||
if (string && ((CharSequence) val).length() == 0) {
|
if (string && ((CharSequence) val).length() == 0) { //空字符串不需要进行过滤
|
||||||
skip = true;
|
skip = true;
|
||||||
} else if (number && ((Number) val).longValue() < least) {
|
} else if (number && ((Number) val).longValue() < least) { //数值小于过滤下值限则不需要过滤
|
||||||
skip = true;
|
skip = true;
|
||||||
}
|
}
|
||||||
if (!skip) {
|
if (!skip) {
|
||||||
if (this.joinClass == null) {
|
if (this.joinClass == null) {
|
||||||
node = FilterNode.create(column, express, val);
|
node = FilterNode.create(column, express, itemand, val);
|
||||||
} else {
|
} else {
|
||||||
node = FilterJoinNode.create(joinClass, joinColumns, column, express, val);
|
node = FilterJoinNode.create(joinClass, joinColumns, column, express, itemand, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -221,7 +228,7 @@ public final class FilterNodeBean<T> implements Comparable<FilterNodeBean<T>> {
|
|||||||
if (f == null) continue;
|
if (f == null) continue;
|
||||||
rs = rs == null ? f : rs.and(f);
|
rs = rs == null ? f : rs.and(f);
|
||||||
}
|
}
|
||||||
if (rs !=null && rs.nodeBeans != null) Arrays.sort(rs.nodeBeans);
|
if (rs != null && rs.nodeBeans != null) Arrays.sort(rs.nodeBeans);
|
||||||
return rs == null ? new FilterNodeBean(null) : rs;
|
return rs == null ? new FilterNodeBean(null) : rs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user