新版FilterNodeBean
This commit is contained in:
@@ -8,6 +8,7 @@ package com.wentch.redkale.source;
|
|||||||
import com.wentch.redkale.util.*;
|
import com.wentch.redkale.util.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.atomic.*;
|
||||||
import java.util.function.*;
|
import java.util.function.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,75 +40,149 @@ public class FilterJoinNode extends FilterNode {
|
|||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FilterNode create(Class joinClass, String joinColumn, String column, Serializable value) {
|
protected FilterJoinNode(FilterJoinNode node) {
|
||||||
|
this(node.joinClass, node.joinColumns, node.column, node.express, node.value);
|
||||||
|
this.joinEntity = node.joinEntity;
|
||||||
|
this.or = node.or;
|
||||||
|
this.nodes = node.nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FilterJoinNode create(Class joinClass, String joinColumn, String column, Serializable value) {
|
||||||
return new FilterJoinNode(joinClass, new String[]{joinColumn}, column, value);
|
return new FilterJoinNode(joinClass, new String[]{joinColumn}, column, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FilterNode 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 new FilterJoinNode(joinClass, new String[]{joinColumn}, column, express, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FilterNode 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 new FilterJoinNode(joinClass, joinColumns, column, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FilterNode 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 new FilterJoinNode(joinClass, joinColumns, column, express, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void check(FilterNode node) {
|
protected FilterNode any(final FilterNode node0, boolean signor) {
|
||||||
Objects.requireNonNull(node);
|
Objects.requireNonNull(node0);
|
||||||
if (!(node instanceof FilterJoinNode)) throw new IllegalArgumentException(this + " check " + String.valueOf(node) + "is not a " + FilterJoinNode.class.getSimpleName());
|
if (!(node0 instanceof FilterJoinNode)) {
|
||||||
|
throw new IllegalArgumentException(this + (signor ? " or " : " and ") + " a node but " + String.valueOf(node0) + "is not a " + FilterJoinNode.class.getSimpleName());
|
||||||
|
}
|
||||||
|
final FilterJoinNode node = (FilterJoinNode) node0;
|
||||||
|
if (this.nodes == null) {
|
||||||
|
this.nodes = new FilterNode[]{node};
|
||||||
|
this.or = signor;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
if (or == signor || this.column == null) {
|
||||||
|
FilterNode[] newsiblings = new FilterNode[nodes.length + 1];
|
||||||
|
System.arraycopy(nodes, 0, newsiblings, 0, nodes.length);
|
||||||
|
newsiblings[nodes.length] = node;
|
||||||
|
this.nodes = newsiblings;
|
||||||
|
if (this.column == null) this.or = signor;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
this.nodes = new FilterNode[]{new FilterJoinNode(node), node};
|
||||||
|
this.column = null;
|
||||||
|
this.express = null;
|
||||||
|
this.value = null;
|
||||||
|
this.joinClass = null;
|
||||||
|
this.joinEntity = null;
|
||||||
|
this.joinColumns = null;
|
||||||
|
this.or = signor;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected <T> CharSequence createSQLExpress(final EntityInfo<T> info, final Map<Class, String> joinTabalis) {
|
protected <T> CharSequence createSQLExpress(final EntityInfo<T> info, final Map<Class, String> joinTabalis) {
|
||||||
return super.createSQLExpress(this.joinEntity, joinTabalis);
|
return super.createSQLExpress(this.joinEntity == null ? info : this.joinEntity, joinTabalis);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected <T, E> Predicate<T> createPredicate(final EntityCache<T> cache) {
|
protected <T, E> Predicate<T> createPredicate(final EntityCache<T> cache) {
|
||||||
if (column == null && this.nodes == null) return null;
|
if (column == null && this.nodes == null) return null;
|
||||||
final EntityCache<E> joinCache = this.joinEntity.getCache();
|
final EntityCache<E> joinCache = this.joinEntity.getCache();
|
||||||
Predicate<E> filter = createChildPredicate();
|
final AtomicBoolean more = new AtomicBoolean();
|
||||||
if (filter == null) return null;
|
Predicate<E> filter = createJoinPredicate(more);
|
||||||
|
Predicate<T> rs = null;
|
||||||
|
if (filter == null && !more.get()) return rs;
|
||||||
|
if (filter != null) {
|
||||||
|
final Predicate<E> inner = filter;
|
||||||
|
rs = new Predicate<T>() {
|
||||||
|
|
||||||
final Predicate<E> inner = filter;
|
@Override
|
||||||
return new Predicate<T>() {
|
public boolean test(final T t) {
|
||||||
|
Predicate<E> joinPredicate = null;
|
||||||
@Override
|
for (String joinColumn : joinColumns) {
|
||||||
public boolean test(final T t) {
|
final Serializable key = cache.getAttribute(joinColumn).get(t);
|
||||||
Predicate<E> joinPredicate = null;
|
final Attribute<E, Serializable> joinAttr = joinCache.getAttribute(joinColumn);
|
||||||
for (String joinColumn : joinColumns) {
|
Predicate<E> p = (E e) -> key.equals(joinAttr.get(e));
|
||||||
final Serializable key = cache.getAttribute(joinColumn).get(t);
|
joinPredicate = joinPredicate == null ? p : joinPredicate.and(p);
|
||||||
final Attribute<E, Serializable> joinAttr = joinCache.getAttribute(joinColumn);
|
}
|
||||||
Predicate<E> p = (E e) -> key.equals(joinAttr.get(e));
|
return joinCache.exists(inner.and(joinPredicate));
|
||||||
joinPredicate = joinPredicate == null ? p : joinPredicate.and(p);
|
|
||||||
}
|
}
|
||||||
return joinCache.exists(inner.and(joinPredicate));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append(" #-- ON ").append(joinColumns[0]).append("=").append(joinClass == null ? "null" : joinClass.getSimpleName()).append(".").append(joinColumns[0]);
|
sb.append(" #-- ON ").append(joinColumns[0]).append("=").append(joinClass == null ? "null" : joinClass.getSimpleName()).append(".").append(joinColumns[0]);
|
||||||
for (int i = 1; i < joinColumns.length; i++) {
|
for (int i = 1; i < joinColumns.length; i++) {
|
||||||
sb.append(" AND ").append(joinColumns[i]).append("=").append(joinClass == null ? "null" : joinClass.getSimpleName()).append(".").append(joinColumns[i]);
|
sb.append(" AND ").append(joinColumns[i]).append("=").append(joinClass == null ? "null" : joinClass.getSimpleName()).append(".").append(joinColumns[i]);
|
||||||
|
}
|
||||||
|
sb.append(" --# ").append(inner.toString());
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (more.get()) { //存在不同Class的关联表
|
||||||
|
if (this.nodes != null) {
|
||||||
|
for (FilterNode node : this.nodes) {
|
||||||
|
if (((FilterJoinNode) node).joinClass == this.joinClass) continue;
|
||||||
|
Predicate<T> f = node.createPredicate(cache);
|
||||||
|
if (f == null) continue;
|
||||||
|
final Predicate<T> one = rs;
|
||||||
|
final Predicate<T> two = f;
|
||||||
|
rs = (rs == null) ? f : (or ? 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 + ")";
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
sb.append(" --# ").append(inner.toString());
|
|
||||||
return sb.toString();
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
return rs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <E> Predicate<E> createChildPredicate() {
|
private <E> Predicate<E> createJoinPredicate(final AtomicBoolean more) {
|
||||||
if (column == null && this.nodes == null) return null;
|
if (column == null && this.nodes == null) return null;
|
||||||
final EntityCache<E> joinCache = this.joinEntity.getCache();
|
final EntityCache<E> joinCache = this.joinEntity.getCache();
|
||||||
Predicate<E> filter = createElementPredicate(joinCache, true);
|
Predicate<E> filter = createElementPredicate(joinCache, true);
|
||||||
if (this.nodes != null) {
|
if (this.nodes != null) {
|
||||||
for (FilterNode node : this.nodes) {
|
for (FilterNode node : this.nodes) {
|
||||||
Predicate<E> f = ((FilterJoinNode) node).createChildPredicate();
|
if (((FilterJoinNode) node).joinClass != this.joinClass) {
|
||||||
|
more.set(true);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Predicate<E> f = ((FilterJoinNode) node).createJoinPredicate(more);
|
||||||
if (f == null) continue;
|
if (f == null) continue;
|
||||||
final Predicate<E> one = filter;
|
final Predicate<E> one = filter;
|
||||||
final Predicate<E> two = f;
|
final Predicate<E> two = f;
|
||||||
@@ -141,21 +216,52 @@ public class FilterJoinNode extends FilterNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected <T> CharSequence createSQLJoin(final Function<Class, EntityInfo> func, final Map<Class, String> joinTabalis, final EntityInfo<T> info) {
|
protected <T> CharSequence createSQLJoin(final Function<Class, EntityInfo> func, final Map<Class, String> joinTabalis, final EntityInfo<T> info) {
|
||||||
|
boolean morejoin = false;
|
||||||
if (this.joinEntity == null) {
|
if (this.joinEntity == null) {
|
||||||
this.joinEntity = func.apply(this.joinClass);
|
if (this.joinClass != null) this.joinEntity = func.apply(this.joinClass);
|
||||||
if (this.nodes != null) {
|
if (this.nodes != null) {
|
||||||
for (FilterNode node : this.nodes) {
|
for (FilterNode node : this.nodes) {
|
||||||
if (node instanceof FilterJoinNode) {
|
if (node instanceof FilterJoinNode) {
|
||||||
((FilterJoinNode) node).joinEntity = func.apply(((FilterJoinNode) node).joinClass);
|
FilterJoinNode joinNode = ((FilterJoinNode) node);
|
||||||
|
if (joinNode.joinClass != null) {
|
||||||
|
joinNode.joinEntity = func.apply(joinNode.joinClass);
|
||||||
|
if (this.joinClass != null && this.joinClass != joinNode.joinClass) morejoin = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append(" INNER JOIN ").append(joinEntity.getTable()).append(" ").append(joinTabalis.get(this.joinClass))
|
if (this.joinClass != null) {
|
||||||
.append(" ON ").append(info.getSQLColumn("a", joinColumns[0])).append(" = ").append(this.joinEntity.getSQLColumn(joinTabalis.get(this.joinClass), joinColumns[0]));
|
sb.append(createElementSQLJoin(joinTabalis, info, this));
|
||||||
|
}
|
||||||
|
if (morejoin) {
|
||||||
|
Set<Class> set = new HashSet<>();
|
||||||
|
if (this.joinClass != null) set.add(this.joinClass);
|
||||||
|
for (FilterNode node : this.nodes) {
|
||||||
|
if (node instanceof FilterJoinNode) {
|
||||||
|
FilterJoinNode joinNode = ((FilterJoinNode) node);
|
||||||
|
if (!set.contains(joinNode.joinClass)) {
|
||||||
|
CharSequence cs = createElementSQLJoin(joinTabalis, info, joinNode);
|
||||||
|
if (cs != null) {
|
||||||
|
sb.append(cs);
|
||||||
|
set.add(joinNode.joinClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CharSequence createElementSQLJoin(final Map<Class, String> joinTabalis, final EntityInfo info, final FilterJoinNode node) {
|
||||||
|
if (node.joinClass == null) return null;
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
String[] joinColumns = node.joinColumns;
|
||||||
|
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]));
|
||||||
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(this.joinEntity.getSQLColumn(joinTabalis.get(this.joinClass), joinColumns[i]));
|
sb.append(" AND ").append(info.getSQLColumn("a", joinColumns[i])).append(" = ").append(node.joinEntity.getSQLColumn(joinTabalis.get(node.joinClass), joinColumns[i]));
|
||||||
}
|
}
|
||||||
return sb;
|
return sb;
|
||||||
}
|
}
|
||||||
@@ -173,7 +279,7 @@ public class FilterJoinNode extends FilterNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void putJoinTabalis(Map<Class, String> map) {
|
protected void putJoinTabalis(Map<Class, String> map) {
|
||||||
if (!map.containsKey(this.joinClass)) map.put(joinClass, String.valueOf((char) ('b' + map.size())));
|
if (this.joinClass != null && !map.containsKey(this.joinClass)) map.put(joinClass, String.valueOf((char) ('b' + map.size())));
|
||||||
if (this.nodes == null) return;
|
if (this.nodes == null) return;
|
||||||
for (FilterNode node : this.nodes) {
|
for (FilterNode node : this.nodes) {
|
||||||
node.putJoinTabalis(map);
|
node.putJoinTabalis(map);
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ public class FilterNode {
|
|||||||
return or(new FilterNode(column, express, value));
|
return or(new FilterNode(column, express, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final FilterNode any(FilterNode node, boolean signor) {
|
protected FilterNode any(FilterNode node, boolean signor) {
|
||||||
Objects.requireNonNull(node);
|
Objects.requireNonNull(node);
|
||||||
if (this.column == null) {
|
if (this.column == null) {
|
||||||
this.column = node.column;
|
this.column = node.column;
|
||||||
@@ -97,7 +97,7 @@ 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.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};
|
||||||
@@ -108,15 +108,6 @@ public class FilterNode {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法需要重载
|
|
||||||
*
|
|
||||||
* @param node
|
|
||||||
*/
|
|
||||||
protected void check(FilterNode node) {
|
|
||||||
Objects.requireNonNull(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 该方法需要重载
|
* 该方法需要重载
|
||||||
*
|
*
|
||||||
@@ -185,11 +176,10 @@ public class FilterNode {
|
|||||||
* @param <T>
|
* @param <T>
|
||||||
* @param joinTabalis
|
* @param joinTabalis
|
||||||
* @param info
|
* @param info
|
||||||
* @param bean
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected <T> CharSequence createSQLExpress(final EntityInfo<T> info, final Map<Class, String> joinTabalis) {
|
protected <T> CharSequence createSQLExpress(final EntityInfo<T> info, final Map<Class, String> joinTabalis) {
|
||||||
CharSequence sb0 = createElementSQLExpress(info, joinTabalis == null ? null : joinTabalis.get(info.getType()));
|
CharSequence sb0 = this.column == null || info == null ? null : createElementSQLExpress(info, joinTabalis == null ? null : joinTabalis.get(info.getType()));
|
||||||
if (this.nodes == null) return sb0;
|
if (this.nodes == null) return sb0;
|
||||||
final StringBuilder rs = new StringBuilder();
|
final StringBuilder rs = new StringBuilder();
|
||||||
rs.append('(');
|
rs.append('(');
|
||||||
|
|||||||
@@ -194,6 +194,8 @@ public final class FilterNodeBean<T> implements Comparable<FilterNodeBean<T>> {
|
|||||||
FilterNodeBean node = nodemap.get(key);
|
FilterNodeBean node = nodemap.get(key);
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
nodemap.put(key, nodeBean);
|
nodemap.put(key, nodeBean);
|
||||||
|
} else if (nodeBean.joinClass == null && node.joinClass != null) { //非joinNode 关联 joinNode
|
||||||
|
nodemap.put(key, nodeBean.any(node, key.substring(key.lastIndexOf('.') + 1).contains("[OR]")));
|
||||||
} else {
|
} else {
|
||||||
node.any(nodeBean, key.substring(key.lastIndexOf('.') + 1).contains("[OR]"));
|
node.any(nodeBean, key.substring(key.lastIndexOf('.') + 1).contains("[OR]"));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user