diff --git a/src/com/wentch/redkale/source/DataDefaultSource.java b/src/com/wentch/redkale/source/DataDefaultSource.java index 28bbf87ca..fd8495a38 100644 --- a/src/com/wentch/redkale/source/DataDefaultSource.java +++ b/src/com/wentch/redkale/source/DataDefaultSource.java @@ -645,9 +645,10 @@ public final class DataDefaultSource implements DataSource, Nameable, Function void delete(final Connection conn, final EntityInfo info, final FilterNode node) { try { if (!info.isVirtualEntity()) { - CharSequence join = node.createSQLJoin(this, info); - CharSequence where = node.createSQLExpress(this, info, null); - String sql = "DELETE FROM " + info.getTable() + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)); + Map joinTabalis = node.getJoinTabalis(); + CharSequence join = node.createSQLJoin(this, joinTabalis, info); + CharSequence where = node.createSQLExpress(info, joinTabalis, null); + String sql = "DELETE a FROM " + info.getTable() + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)); if (debug.get()) logger.finest(info.getType().getSimpleName() + " delete sql=" + sql); final Statement stmt = conn.createStatement(); stmt.execute(sql); @@ -1090,8 +1091,9 @@ public final class DataDefaultSource implements DataSource, Nameable, Function joinTabalis = node == null ? null : node.getJoinTabalis(); + final CharSequence join = node == null ? null : node.createSQLJoin(this, joinTabalis, info); + final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis, bean); final String sql = "SELECT " + reckon.getColumn((column == null || column.isEmpty() ? "*" : ("a." + column))) + " FROM " + info.getTable() + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)); if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(entityClass.getSimpleName() + " single sql=" + sql); @@ -1139,8 +1141,9 @@ public final class DataDefaultSource implements DataSource, Nameable, Function joinTabalis = node == null ? null : node.getJoinTabalis(); + final CharSequence join = node == null ? null : node.createSQLJoin(this, joinTabalis, info); + final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis, bean); final String sql = "SELECT a." + sqlkey + ", " + reckon.getColumn((reckonColumn == null || reckonColumn.isEmpty() ? "*" : ("a." + reckonColumn))) + " FROM " + info.getTable() + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)) + " GROUP BY a." + sqlkey; if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(entityClass.getSimpleName() + " single sql=" + sql); @@ -1224,8 +1227,9 @@ public final class DataDefaultSource implements DataSource, Nameable, Function joinTabalis = node == null ? null : node.getJoinTabalis(); + final CharSequence join = node == null ? null : node.createSQLJoin(this, joinTabalis, info); + final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis, bean); final String sql = "SELECT a.* FROM " + info.getTable() + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)); if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(clazz.getSimpleName() + " find sql=" + sql); final PreparedStatement ps = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); @@ -1282,8 +1286,9 @@ public final class DataDefaultSource implements DataSource, Nameable, Function joinTabalis = node == null ? null : node.getJoinTabalis(); + final CharSequence join = node == null ? null : node.createSQLJoin(this, joinTabalis, info); + final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis, bean); final String sql = "SELECT COUNT(" + info.getPrimarySQLColumn("a") + ") FROM " + info.getTable() + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)); if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(clazz.getSimpleName() + " exists sql=" + sql); final PreparedStatement ps = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); @@ -1536,8 +1541,9 @@ public final class DataDefaultSource implements DataSource, Nameable, Function list = new ArrayList(); - final CharSequence join = node == null ? null : node.createSQLJoin(this, info); - final CharSequence where = node == null ? null : node.createSQLExpress(this, info, bean); + final Map joinTabalis = node == null ? null : node.getJoinTabalis(); + final CharSequence join = node == null ? null : node.createSQLJoin(this, joinTabalis, info); + final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis, bean); final String sql = "SELECT a.* FROM " + info.getTable() + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)) + info.createSQLOrderby(flipper); if (debug.get() && info.isLoggable(Level.FINEST)) diff --git a/src/com/wentch/redkale/source/EntityInfo.java b/src/com/wentch/redkale/source/EntityInfo.java index 867ea3efb..8fffdf93a 100644 --- a/src/com/wentch/redkale/source/EntityInfo.java +++ b/src/com/wentch/redkale/source/EntityInfo.java @@ -247,6 +247,10 @@ public final class EntityInfo { return cache; } + public boolean isCacheFullLoaded() { + return cache != null && cache.isFullLoaded(); + } + public Creator getCreator() { return creator; } diff --git a/src/com/wentch/redkale/source/FilterBeanNode.java b/src/com/wentch/redkale/source/FilterBeanNode.java index e12000a6c..c6cf35db2 100644 --- a/src/com/wentch/redkale/source/FilterBeanNode.java +++ b/src/com/wentch/redkale/source/FilterBeanNode.java @@ -90,7 +90,7 @@ final class FilterBeanNode extends FilterNode { } final String jc = joinCol.column().isEmpty() ? secinfo.getPrimary().field() : joinCol.column(); if (first) { - joinsb.append(" ").append(joinCol.type().name()).append(" JOIN ").append(secinfo.getTable()) + joinsb.append(" INNER JOIN ").append(secinfo.getTable()) .append(" ").append(alias).append(" ON ").append(secinfo.getSQLColumn("a", jc)).append(" = ").append(secinfo.getSQLColumn(alias, jc)); } newnode.foreignCache = secinfo.getCache(); @@ -189,7 +189,6 @@ final class FilterBeanNode extends FilterNode { this.tabalis = "a"; } - @Override protected String getTabalis() { return tabalis; } @@ -225,13 +224,13 @@ final class FilterBeanNode extends FilterNode { } @Override - protected CharSequence createSQLJoin(final Function func, final EntityInfo info) { + protected CharSequence createSQLJoin(final Function func, final Map joinTabalis, final EntityInfo info) { if (joinSQL == null) return null; return joinSQL; } @Override - protected Predicate createPredicate(final EntityCache cache, FilterBean bean) { + protected Predicate createPredicate(final EntityCache cache, FilterBean bean) { if (this.foreignCache == null) return super.createPredicate(cache, bean); final Map foreign = new HashMap<>(); Predicate result = null; @@ -336,7 +335,7 @@ final class FilterBeanNode extends FilterNode { public String toString() { return "" + or; } - } : super.createElementPredicate(cache, this.columnAttribute, bean); + } : super.createElementPredicate(cache, false, this.columnAttribute, bean); if (filter == null) return; Predicate p = foreign.get(this.foreignCache); if (p == null) { diff --git a/src/com/wentch/redkale/source/FilterJoinColumn.java b/src/com/wentch/redkale/source/FilterJoinColumn.java index 96ca22705..1776d7f68 100644 --- a/src/com/wentch/redkale/source/FilterJoinColumn.java +++ b/src/com/wentch/redkale/source/FilterJoinColumn.java @@ -19,11 +19,6 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(RUNTIME) public @interface FilterJoinColumn { - public enum JoinType { //不能支持RIGHT, 因为right获取的主对象都是null - - INNER; - } - /** * 关联表 通常join表默认别名为b/c/d/...自增, 被join表默认别名为a * @@ -38,5 +33,4 @@ public @interface FilterJoinColumn { */ String column() default ""; - JoinType type() default JoinType.INNER; } diff --git a/src/com/wentch/redkale/source/FilterJoinNode.java b/src/com/wentch/redkale/source/FilterJoinNode.java index 1684fcee1..f37e65444 100644 --- a/src/com/wentch/redkale/source/FilterJoinNode.java +++ b/src/com/wentch/redkale/source/FilterJoinNode.java @@ -5,7 +5,9 @@ */ package com.wentch.redkale.source; +import com.wentch.redkale.util.*; import java.io.*; +import java.util.*; import java.util.function.*; /** @@ -14,10 +16,10 @@ import java.util.function.*; */ public class FilterJoinNode extends FilterNode { - private String tabalis; - private Class joinClass; + private EntityInfo joinEntity; //在调用 createSQLJoin 和 isCacheUseable 时会注入 + private String joinColumn; public FilterJoinNode() { @@ -28,6 +30,8 @@ public class FilterJoinNode extends FilterNode { } protected FilterJoinNode(Class joinClass, String joinColumn, String column, FilterExpress express, Serializable value) { + Objects.requireNonNull(joinClass); + Objects.requireNonNull(joinColumn); this.joinClass = joinClass; this.joinColumn = joinColumn; this.column = column; @@ -44,9 +48,115 @@ public class FilterJoinNode extends FilterNode { } @Override - protected CharSequence createSQLExpress(final Function func, final EntityInfo info, final FilterBean bean) { - if (this.joinClass == null) return super.createSQLExpress(func, info, bean); - return super.createSQLExpress(func, func.apply(joinClass), bean); + protected CharSequence createSQLExpress(final EntityInfo info, final Map joinTabalis, final FilterBean bean) { + return super.createSQLExpress(this.joinEntity, joinTabalis, bean); + } + + @Override + protected Predicate createPredicate(final EntityCache cache, final FilterBean bean) { + if (column == null && this.nodes == null) return null; + final EntityCache joinCache = this.joinEntity.getCache(); + Predicate filter = createChildPredicate(bean); + if (filter == null) return null; + final Attribute attr = cache.getAttribute(this.joinColumn); + final Attribute joinAttr = joinCache.getAttribute(this.joinColumn); + final Predicate inner = filter; + return new Predicate() { + + @Override + public boolean test(T t) { + return joinCache.exists(inner.and((e) -> attr.get(t).equals(joinAttr.get(e)))); + } + + @Override + public String toString() { + return " # ON " + joinColumn + "=" + (joinClass == null ? "null" : joinClass.getSimpleName()) + "." + joinColumn + " # " + inner.toString(); + } + }; + } + + private Predicate createChildPredicate(final FilterBean bean) { + if (column == null && this.nodes == null) return null; + final EntityCache joinCache = this.joinEntity.getCache(); + Predicate filter = createElementPredicate(joinCache, true, bean); + if (this.nodes != null) { + for (FilterNode node : this.nodes) { + Predicate f = ((FilterJoinNode) node).createChildPredicate(bean); + if (f == null) continue; + final Predicate one = filter; + final Predicate two = f; + filter = (filter == null) ? f : (or ? new Predicate() { + + @Override + public boolean test(E t) { + return one.test(t) || two.test(t); + } + + @Override + public String toString() { + return "(" + one + " OR " + two + ")"; + } + } : new Predicate() { + + @Override + public boolean test(E t) { + return one.test(t) && two.test(t); + } + + @Override + public String toString() { + return "(" + one + " AND " + two + ")"; + } + }); + } + } + return filter; + } + + @Override + protected CharSequence createSQLJoin(final Function func, final Map joinTabalis, final EntityInfo info) { + if (this.joinEntity == 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); + } + } + } + } + return new StringBuilder().append(" INNER JOIN ").append(joinEntity.getTable()).append(" ").append(joinTabalis.get(this.joinClass)) + .append(" ON ").append(info.getSQLColumn("a", joinColumn)).append(" = ").append(this.joinEntity.getSQLColumn(joinTabalis.get(this.joinClass), joinColumn)); + } + + @Override + protected boolean isCacheUseable(final Function entityApplyer) { + if (this.joinEntity == null) this.joinEntity = entityApplyer.apply(this.joinClass); + if (!this.joinEntity.isCacheFullLoaded()) return false; + if (this.nodes == null) return true; + for (FilterNode node : this.nodes) { + if (!node.isCacheUseable(entityApplyer)) return false; + } + return true; + } + + @Override + protected void putJoinTabalis(Map map) { + if (!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); + } + } + + @Override + protected final boolean isjoin() { + return true; + } + + @Override + public String toString() { + return toString(joinClass == null ? null : joinClass.getSimpleName(), null); } public Class getJoinClass() { @@ -65,13 +175,4 @@ public class FilterJoinNode extends FilterNode { this.joinColumn = joinColumn; } - @Override - public String getTabalis() { - return tabalis; - } - - public void setTabalis(String tabalis) { - this.tabalis = tabalis; - } - } diff --git a/src/com/wentch/redkale/source/FilterNode.java b/src/com/wentch/redkale/source/FilterNode.java index 9f2186ebd..29e70e99a 100644 --- a/src/com/wentch/redkale/source/FilterNode.java +++ b/src/com/wentch/redkale/source/FilterNode.java @@ -13,6 +13,9 @@ import java.util.*; import java.util.function.*; /** + * 注意: + * 在调用 createSQLExpress 之前必须先调用 createSQLJoin + * 在调用 createPredicate 之前必须先调用 isCacheUseable * * @author zhangjx */ @@ -82,8 +85,8 @@ public class FilterNode { this.value = node.value; return this; } - if (nodes == null) { - nodes = new FilterNode[]{node}; + if (this.nodes == null) { + this.nodes = new FilterNode[]{node}; this.or = sign; return this; } @@ -130,11 +133,20 @@ public class FilterNode { * * @param * @param func + * @param joinTabalis * @param info * @return */ - protected CharSequence createSQLJoin(final Function func, final EntityInfo info) { - return null; + protected CharSequence createSQLJoin(final Function func, final Map joinTabalis, final EntityInfo info) { + if (joinTabalis == null || this.nodes == null) return null; + StringBuilder sb = null; + for (FilterNode node : this.nodes) { + CharSequence cs = node.createSQLJoin(func, joinTabalis, info); + if (cs == null) continue; + if (sb == null) sb = new StringBuilder(); + sb.append(cs); + } + return sb; } /** @@ -142,8 +154,26 @@ public class FilterNode { * * @return */ - protected String getTabalis() { - return null; + protected boolean isjoin() { + if (this.nodes == null) return false; + for (FilterNode node : this.nodes) { + if (node.isjoin()) return true; + } + return false; + } + + protected final Map getJoinTabalis() { + if (!isjoin()) return null; + Map map = new HashMap<>(); + putJoinTabalis(map); + return map; + } + + protected void putJoinTabalis(Map map) { + if (this.nodes == null) return; + for (FilterNode node : this.nodes) { + node.putJoinTabalis(map); + } } /** @@ -164,13 +194,13 @@ public class FilterNode { * 该方法需要重载 * * @param - * @param func + * @param joinTabalis * @param info * @param bean * @return */ - protected CharSequence createSQLExpress(final Function func, final EntityInfo info, final FilterBean bean) { - CharSequence sb0 = createElementSQLExpress(info, getTabalis(), bean); + protected CharSequence createSQLExpress(final EntityInfo info, final Map joinTabalis, final FilterBean bean) { + CharSequence sb0 = createElementSQLExpress(info, joinTabalis == null ? null : joinTabalis.get(info.getType()), bean); if (this.nodes == null) return sb0; final StringBuilder rs = new StringBuilder(); rs.append('('); @@ -180,7 +210,7 @@ public class FilterNode { rs.append(sb0); } for (FilterNode node : this.nodes) { - CharSequence f = node.createSQLExpress(func, info, bean); + CharSequence f = node.createSQLExpress(info, joinTabalis, bean); if (f == null || f.length() < 3) continue; if (more) rs.append(or ? " OR " : " AND "); rs.append(f); @@ -203,9 +233,7 @@ public class FilterNode { if (column == null) return null; if (talis == null) talis = "a"; if (express == ISNULL || express == ISNOTNULL) { - StringBuilder sb = new StringBuilder(); - sb.append(info.getSQLColumn(talis, column)).append(' ').append(express.value()); - return sb; + return new StringBuilder().append(info.getSQLColumn(talis, column)).append(' ').append(express.value()); } final CharSequence val = formatToString(express, getElementValue(bean)); if (val == null) return null; @@ -231,9 +259,9 @@ public class FilterNode { return sb; } - protected Predicate createPredicate(final EntityCache cache, final FilterBean bean) { + protected Predicate createPredicate(final EntityCache cache, final FilterBean bean) { if (cache == null || (column == null && this.nodes == null)) return null; - Predicate filter = createElementPredicate(cache, bean); + Predicate filter = createElementPredicate(cache, false, bean); if (this.nodes == null) return filter; for (FilterNode node : this.nodes) { Predicate f = node.createPredicate(cache, bean); @@ -267,12 +295,14 @@ public class FilterNode { return filter; } - protected final Predicate createElementPredicate(final EntityCache cache, final FilterBean bean) { - return createElementPredicate(cache, cache.getAttribute(column), bean); + protected final Predicate createElementPredicate(final EntityCache cache, final boolean join, final FilterBean bean) { + if (column == null) return null; + return createElementPredicate(cache, join, cache.getAttribute(column), bean); } - protected final Predicate createElementPredicate(final EntityCache cache, final Attribute attr, final FilterBean bean) { - + protected final Predicate createElementPredicate(final EntityCache cache, final boolean join, final Attribute attr, final FilterBean bean) { + if (attr == null) return null; + final String field = join ? (cache.getType().getSimpleName() + "." + attr.field()) : attr.field(); if (express == ISNULL) return new Predicate() { @Override @@ -282,7 +312,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + " = null"; + return field + " = null"; } }; if (express == ISNOTNULL) return new Predicate() { @@ -294,7 +324,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + " != null"; + return field + " != null"; } }; if (attr == null) return null; @@ -424,7 +454,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + ' ' + express.value() + ' ' + val; + return field + ' ' + express.value() + ' ' + formatToString(val); } }; case NOTEQUAL: return new Predicate() { @@ -436,7 +466,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + ' ' + express.value() + ' ' + val; + return field + ' ' + express.value() + ' ' + formatToString(val); } }; case GREATERTHAN: return new Predicate() { @@ -448,7 +478,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + ' ' + express.value() + ' ' + val; + return field + ' ' + express.value() + ' ' + val; } }; case LESSTHAN: return new Predicate() { @@ -460,7 +490,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + ' ' + express.value() + ' ' + val; + return field + ' ' + express.value() + ' ' + val; } }; case GREATERTHANOREQUALTO: return new Predicate() { @@ -472,7 +502,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + ' ' + express.value() + ' ' + val; + return field + ' ' + express.value() + ' ' + val; } }; case LESSTHANOREQUALTO: return new Predicate() { @@ -484,7 +514,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + ' ' + express.value() + ' ' + val; + return field + ' ' + express.value() + ' ' + val; } }; @@ -497,7 +527,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + " & " + val + " > 0"; + return field + " & " + val + " > 0"; } }; case OPOR: return new Predicate() { @@ -509,7 +539,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + " | " + val + " > 0"; + return field + " | " + val + " > 0"; } }; case OPANDNO: return new Predicate() { @@ -521,7 +551,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + " & " + val + " = 0"; + return field + " & " + val + " = 0"; } }; case LIKE: @@ -535,7 +565,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + ' ' + express.value() + ' ' + val; + return field + ' ' + express.value() + ' ' + formatToString(val); } }; case IGNORECASELIKE: @@ -550,7 +580,7 @@ public class FilterNode { @Override public String toString() { - return "LOWER(" + attr.field() + ") " + express.value() + ' ' + valstr; + return "LOWER(" + field + ") " + express.value() + ' ' + formatToString(valstr); } }; case NOTLIKE: @@ -564,7 +594,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + ' ' + express.value() + ' ' + val; + return field + ' ' + express.value() + ' ' + formatToString(val); } }; case IGNORECASENOTLIKE: @@ -579,7 +609,7 @@ public class FilterNode { @Override public String toString() { - return "LOWER(" + attr.field() + ") " + express.value() + ' ' + valstr2; + return "LOWER(" + field + ") " + express.value() + ' ' + formatToString(valstr2); } }; case BETWEEN: @@ -599,7 +629,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + " BETWEEN " + min + " AND " + max; + return field + " BETWEEN " + min + " AND " + max; } }; if (express == NOTBETWEEN) return new Predicate() { @@ -614,7 +644,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + " NOT BETWEEN " + min + " AND " + max; + return field + " NOT BETWEEN " + min + " AND " + max; } }; return null; @@ -633,7 +663,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + ' ' + express.value() + " []"; + return field + ' ' + express.value() + " []"; } }; } else { @@ -647,7 +677,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + ' ' + express.value() + ' ' + val; + return field + ' ' + express.value() + ' ' + val; } }; } @@ -663,7 +693,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + ' ' + express.value() + " []"; + return field + ' ' + express.value() + " []"; } }; } else if (type == int[].class) { @@ -682,7 +712,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + ' ' + express.value() + ' ' + Arrays.toString((int[]) val); + return field + ' ' + express.value() + ' ' + Arrays.toString((int[]) val); } }; } else if (type == short[].class) { @@ -701,7 +731,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + ' ' + express.value() + ' ' + Arrays.toString((short[]) val); + return field + ' ' + express.value() + ' ' + Arrays.toString((short[]) val); } }; } else if (type == long[].class) { @@ -720,7 +750,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + ' ' + express.value() + ' ' + Arrays.toString((long[]) val); + return field + ' ' + express.value() + ' ' + Arrays.toString((long[]) val); } }; } else if (type == float[].class) { @@ -739,7 +769,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + ' ' + express.value() + ' ' + Arrays.toString((float[]) val); + return field + ' ' + express.value() + ' ' + Arrays.toString((float[]) val); } }; } else if (type == double[].class) { @@ -758,7 +788,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + ' ' + express.value() + ' ' + Arrays.toString((double[]) val); + return field + ' ' + express.value() + ' ' + Arrays.toString((double[]) val); } }; } else { @@ -776,7 +806,7 @@ public class FilterNode { @Override public String toString() { - return attr.field() + ' ' + express.value() + ' ' + Arrays.toString((Object[]) val); + return field + ' ' + express.value() + ' ' + Arrays.toString((Object[]) val); } }; } @@ -803,29 +833,31 @@ public class FilterNode { @Override public String toString() { - return toString(null); + return toString(null, null); } - protected String toString(final FilterBean bean) { + protected String toString(final String prefix, final FilterBean bean) { StringBuilder sb = new StringBuilder(); if (nodes == null) { if (column != null) { + String col = prefix == null ? column : (prefix + "." + column); Serializable ev = getElementValue(bean); if (express == ISNULL || express == ISNOTNULL) { - sb.append(column).append(' ').append(express.value()); + sb.append(col).append(' ').append(express.value()); } else if (ev != null) { - sb.append((express == IGNORECASELIKE || express == IGNORECASENOTLIKE) ? ("LOWER(" + column + ')') : column).append(' ').append(express.value()).append(' ').append(formatToString(express, ev)); + sb.append((express == IGNORECASELIKE || express == IGNORECASENOTLIKE) ? ("LOWER(" + col + ')') : col).append(' ').append(express.value()).append(' ').append(formatToString(express, ev)); } } } else { boolean more = false; if (column != null) { + String col = prefix == null ? column : (prefix + "." + column); Serializable ev = getElementValue(bean); if (express == ISNULL || express == ISNOTNULL) { - sb.append('(').append(column).append(' ').append(express.value()); + sb.append('(').append(col).append(' ').append(express.value()); more = true; } else if (ev != null) { - sb.append('(').append((express == IGNORECASELIKE || express == IGNORECASENOTLIKE) ? ("LOWER(" + column + ')') : column).append(' ').append(express.value()).append(' ').append(formatToString(express, ev)); + sb.append('(').append((express == IGNORECASELIKE || express == IGNORECASENOTLIKE) ? ("LOWER(" + col + ')') : col).append(' ').append(express.value()).append(' ').append(formatToString(express, ev)); more = true; } }