From 5c0f97d62bc28977d6c968ba28ebf6aa26d220f6 Mon Sep 17 00:00:00 2001 From: kamhung <22250530@qq.com> Date: Fri, 4 Dec 2015 21:00:22 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E7=89=88FilterNodeBean?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wentch/redkale/source/FilterJoinNode.java | 186 ++++++++++++++---- src/com/wentch/redkale/source/FilterNode.java | 16 +- .../wentch/redkale/source/FilterNodeBean.java | 2 + 3 files changed, 151 insertions(+), 53 deletions(-) diff --git a/src/com/wentch/redkale/source/FilterJoinNode.java b/src/com/wentch/redkale/source/FilterJoinNode.java index 4dc4fad23..98951f0fd 100644 --- a/src/com/wentch/redkale/source/FilterJoinNode.java +++ b/src/com/wentch/redkale/source/FilterJoinNode.java @@ -8,6 +8,7 @@ package com.wentch.redkale.source; import com.wentch.redkale.util.*; import java.io.*; import java.util.*; +import java.util.concurrent.atomic.*; import java.util.function.*; /** @@ -39,75 +40,149 @@ public class FilterJoinNode extends FilterNode { 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); } - 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); } - 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); } - 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); } @Override - protected void check(FilterNode node) { - Objects.requireNonNull(node); - if (!(node instanceof FilterJoinNode)) throw new IllegalArgumentException(this + " check " + String.valueOf(node) + "is not a " + FilterJoinNode.class.getSimpleName()); + protected FilterNode any(final FilterNode node0, boolean signor) { + Objects.requireNonNull(node0); + 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 protected CharSequence createSQLExpress(final EntityInfo info, final Map joinTabalis) { - return super.createSQLExpress(this.joinEntity, joinTabalis); + return super.createSQLExpress(this.joinEntity == null ? info : this.joinEntity, joinTabalis); } @Override protected Predicate createPredicate(final EntityCache cache) { if (column == null && this.nodes == null) return null; final EntityCache joinCache = this.joinEntity.getCache(); - Predicate filter = createChildPredicate(); - if (filter == null) return null; + final AtomicBoolean more = new AtomicBoolean(); + Predicate filter = createJoinPredicate(more); + Predicate rs = null; + if (filter == null && !more.get()) return rs; + if (filter != null) { + final Predicate inner = filter; + rs = new Predicate() { - final Predicate inner = filter; - return new Predicate() { - - @Override - public boolean test(final T t) { - Predicate joinPredicate = null; - for (String joinColumn : joinColumns) { - final Serializable key = cache.getAttribute(joinColumn).get(t); - final Attribute joinAttr = joinCache.getAttribute(joinColumn); - Predicate p = (E e) -> key.equals(joinAttr.get(e)); - joinPredicate = joinPredicate == null ? p : joinPredicate.and(p); + @Override + public boolean test(final T t) { + Predicate joinPredicate = null; + for (String joinColumn : joinColumns) { + final Serializable key = cache.getAttribute(joinColumn).get(t); + final Attribute joinAttr = joinCache.getAttribute(joinColumn); + Predicate p = (E e) -> key.equals(joinAttr.get(e)); + joinPredicate = joinPredicate == null ? p : joinPredicate.and(p); + } + return joinCache.exists(inner.and(joinPredicate)); } - return joinCache.exists(inner.and(joinPredicate)); - } - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - 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++) { - sb.append(" AND ").append(joinColumns[i]).append("=").append(joinClass == null ? "null" : joinClass.getSimpleName()).append(".").append(joinColumns[i]); + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + 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++) { + 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 f = node.createPredicate(cache); + if (f == null) continue; + final Predicate one = rs; + final Predicate two = f; + rs = (rs == null) ? f : (or ? new Predicate() { + + @Override + public boolean test(T t) { + return one.test(t) || two.test(t); + } + + @Override + public String toString() { + return "(" + one + " OR " + two + ")"; + } + } : new Predicate() { + + @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 Predicate createChildPredicate() { + private Predicate createJoinPredicate(final AtomicBoolean more) { if (column == null && this.nodes == null) return null; final EntityCache joinCache = this.joinEntity.getCache(); Predicate filter = createElementPredicate(joinCache, true); if (this.nodes != null) { for (FilterNode node : this.nodes) { - Predicate f = ((FilterJoinNode) node).createChildPredicate(); + if (((FilterJoinNode) node).joinClass != this.joinClass) { + more.set(true); + continue; + } + Predicate f = ((FilterJoinNode) node).createJoinPredicate(more); if (f == null) continue; final Predicate one = filter; final Predicate two = f; @@ -141,21 +216,52 @@ public class FilterJoinNode extends FilterNode { @Override protected CharSequence createSQLJoin(final Function func, final Map joinTabalis, final EntityInfo info) { + boolean morejoin = false; if (this.joinEntity == null) { - this.joinEntity = func.apply(this.joinClass); + if (this.joinClass != null) this.joinEntity = func.apply(this.joinClass); if (this.nodes != null) { for (FilterNode node : this.nodes) { 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(); - sb.append(" INNER JOIN ").append(joinEntity.getTable()).append(" ").append(joinTabalis.get(this.joinClass)) - .append(" ON ").append(info.getSQLColumn("a", joinColumns[0])).append(" = ").append(this.joinEntity.getSQLColumn(joinTabalis.get(this.joinClass), joinColumns[0])); + if (this.joinClass != null) { + sb.append(createElementSQLJoin(joinTabalis, info, this)); + } + if (morejoin) { + Set 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 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++) { - 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; } @@ -173,7 +279,7 @@ public class FilterJoinNode extends FilterNode { @Override protected void putJoinTabalis(Map 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; for (FilterNode node : this.nodes) { node.putJoinTabalis(map); diff --git a/src/com/wentch/redkale/source/FilterNode.java b/src/com/wentch/redkale/source/FilterNode.java index 171be0476..9b61a11eb 100644 --- a/src/com/wentch/redkale/source/FilterNode.java +++ b/src/com/wentch/redkale/source/FilterNode.java @@ -77,7 +77,7 @@ public class FilterNode { 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); if (this.column == null) { this.column = node.column; @@ -97,7 +97,7 @@ public class FilterNode { this.nodes = newsiblings; 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.nodes = this.nodes; this.nodes = new FilterNode[]{newnode, node}; @@ -108,15 +108,6 @@ public class FilterNode { return this; } - /** - * 该方法需要重载 - * - * @param node - */ - protected void check(FilterNode node) { - Objects.requireNonNull(node); - } - /** * 该方法需要重载 * @@ -185,11 +176,10 @@ public class FilterNode { * @param * @param joinTabalis * @param info - * @param bean * @return */ protected CharSequence createSQLExpress(final EntityInfo info, final Map 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; final StringBuilder rs = new StringBuilder(); rs.append('('); diff --git a/src/com/wentch/redkale/source/FilterNodeBean.java b/src/com/wentch/redkale/source/FilterNodeBean.java index 9a2f466e1..6d321b341 100644 --- a/src/com/wentch/redkale/source/FilterNodeBean.java +++ b/src/com/wentch/redkale/source/FilterNodeBean.java @@ -194,6 +194,8 @@ public final class FilterNodeBean implements Comparable> { FilterNodeBean node = nodemap.get(key); if (node == null) { 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 { node.any(nodeBean, key.substring(key.lastIndexOf('.') + 1).contains("[OR]")); }