改版EntityXInfo

This commit is contained in:
地平线
2015-05-31 17:36:42 +08:00
parent 9a86fa4b63
commit 93af3d7f1a
4 changed files with 194 additions and 12 deletions

View File

@@ -1749,7 +1749,7 @@ public final class DataJDBCSource implements DataSource {
if (valid) filter = finfo.getFilterPredicate(info, bean);
}
if (valid) {
Sheet<T> sheet = cache.querySheet(selects, filter, flipper, FilterNode.getSortComparator(info, flipper));
Sheet<T> sheet = cache.querySheet(selects, filter, flipper, FilterNode.createFilterComparator(info, flipper));
if (!sheet.isEmpty() || cache.isFullLoaded()) return sheet;
}
}

View File

@@ -209,7 +209,7 @@ public final class EntityInfo<T> {
this.allocationSize = allocationSize0;
//----------------cache--------------
Cacheable c = type.getAnnotation(Cacheable.class);
boolean cf = (c == null) ? (cacheClasses != null && cacheClasses.contains(type)) : false;
boolean cf = (c == null && cacheClasses != null && cacheClasses.contains(type));
if ((c != null && c.value()) || cf) {
this.cache = new EntityCache<>(type, creator, primary, attributes, fullloader);
} else {

View File

@@ -6,19 +6,141 @@
package com.wentch.redkale.source;
import static com.wentch.redkale.source.FilterExpress.*;
import com.wentch.redkale.util.Attribute;
import com.wentch.redkale.util.*;
import java.io.Serializable;
import java.lang.reflect.*;
import java.util.Collection;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.logging.Logger;
import javax.persistence.Transient;
/**
*
* @author zhangjx
*/
public class FilterBeanNode extends FilterNode {
@SuppressWarnings("unchecked")
final class FilterBeanNode extends FilterNode {
private static final Logger logger = Logger.getLogger(FilterBeanNode.class.getSimpleName());
private static final ConcurrentHashMap<Class, FilterBeanNode> beanodes = new ConcurrentHashMap<>();
public static <T extends FilterBean> FilterBeanNode load(Class<T> clazz, final int nodeid,
Function<Class, List> fullloader) {
FilterBeanNode rs = beanodes.get(clazz);
if (rs != null) return rs;
synchronized (beanodes) {
rs = beanodes.get(clazz);
if (rs == null) {
rs = createNode(clazz, nodeid, fullloader);
beanodes.put(clazz, rs);
}
return rs;
}
}
private static <T extends FilterBean> FilterBeanNode createNode(Class<T> clazz, final int nodeid,
Function<Class, List> fullloader) {
Class cltmp = clazz;
Set<String> fields = new HashSet<>();
final Map<Class, String> joinTables = new HashMap<>();
Map<String, FilterBeanNode> nodemap = new HashMap<>();
boolean joinallcached = true;
final StringBuilder joinsb = new StringBuilder();
do {
for (Field field : cltmp.getDeclaredFields()) {
if (Modifier.isStatic(field.getModifiers())) continue;
if (fields.contains(field.getName())) continue;
if (field.getAnnotation(Ignore.class) != null) continue;
if (field.getAnnotation(Transient.class) != null) continue;
char[] chars = field.getName().toCharArray();
chars[0] = Character.toUpperCase(chars[0]);
final Class t = field.getType();
Method getter = null;
try {
getter = cltmp.getMethod(((t == boolean.class || t == Boolean.class) ? "is" : "get") + new String(chars));
} catch (Exception ex) {
continue;
}
fields.add(field.getName());
FilterBeanNode newnode = new FilterBeanNode(field.getName(), true, Attribute.create(getter, null));
newnode.setField(field);
//------------------------------------
{
FilterJoinColumn joinCol = field.getAnnotation(FilterJoinColumn.class);
if (joinCol != null) {
boolean first = false;
final Class joinClass = joinCol.table();
if (!joinTables.containsKey(joinClass)) {
first = true;
joinTables.put(joinClass, String.valueOf((char) ('b' + joinTables.size())));
}
final String alias = joinTables.get(joinClass);
final EntityInfo secinfo = EntityInfo.load(joinClass, nodeid, fullloader);
if (secinfo.getCache() == null || !secinfo.getCache().isFullLoaded()) {
joinallcached = false;
}
if (first) {
joinsb.append(" ").append(joinCol.type().name()).append(" JOIN ").append(secinfo.getTable())
.append(" ").append(alias).append(" ON a.# = ").append(alias).append(".")
.append(joinCol.column().isEmpty() ? secinfo.getPrimarySQLColumn() : secinfo.getSQLColumn(joinCol.column()));
}
newnode.foreignEntity = secinfo;
newnode.tabalis = alias;
newnode.foreignColumn = joinCol.column().isEmpty() ? secinfo.getPrimary().field() : joinCol.column();
}
}
//------------------------------------
{
FilterGroup[] refs = field.getAnnotationsByType(FilterGroup.class);
String[] groups = new String[refs.length];
for (int i = 0; i < refs.length; i++) {
groups[i] = refs[i].value();
}
if (groups.length == 0) groups = new String[]{"[AND]"};
for (String key : groups) {
if (!key.startsWith("[AND]") && !key.startsWith("[OR]")) {
throw new RuntimeException(field + "'s FilterGroup.value(" + key + ") illegal, must be [AND] or [OR] startsWith");
}
FilterBeanNode node = nodemap.get(key);
if (node == null) {
nodemap.put(key, newnode);
} else {
node.any(node, !key.contains("[OR]"));
}
}
}
}
} while ((cltmp = cltmp.getSuperclass()) != Object.class);
FilterBeanNode rs = null;
for (FilterBeanNode f : nodemap.values()) {
if (rs == null) {
rs = f;
} else {
rs.and(f);
}
}
if (rs != null) {
rs.joinallcached = joinallcached;
if (joinsb.length() > 0) rs.joinSQL = joinsb.toString();
}
return rs;
}
//--------------------------- only header -----------------------------------------------------
private boolean joinallcached = true;
private String joinSQL;
//---------------------------------------------------------------------------------------------
private Attribute beanAttribute;
private EntityInfo foreignEntity;
private String foreignColumn;
private boolean array;
private boolean collection;
@@ -39,7 +161,7 @@ public class FilterBeanNode extends FilterNode {
this.beanAttribute = beanAttr;
}
void setField(Field field) {
private void setField(Field field) {
final FilterColumn fc = field.getAnnotation(FilterColumn.class);
if (fc != null && !fc.name().isEmpty()) this.column = fc.name();
final Class type = field.getType();
@@ -63,6 +185,7 @@ public class FilterBeanNode extends FilterNode {
}
if (exp == null) exp = EQUAL;
this.express = exp;
this.tabalis = "a";
}
@Override
@@ -70,6 +193,8 @@ public class FilterBeanNode extends FilterNode {
FilterBeanNode newnode = new FilterBeanNode(this.column, this.signand, this.beanAttribute);
newnode.express = this.express;
newnode.nodes = this.nodes;
newnode.foreignEntity = this.foreignEntity;
newnode.foreignColumn = this.foreignColumn;
newnode.array = this.array;
newnode.collection = this.collection;
newnode.ignoreCase = this.ignoreCase;
@@ -85,6 +210,8 @@ public class FilterBeanNode extends FilterNode {
if (node instanceof FilterBeanNode) {
FilterBeanNode beanNode = ((FilterBeanNode) node);
this.beanAttribute = beanNode.beanAttribute;
this.foreignEntity = beanNode.foreignEntity;
this.foreignColumn = beanNode.foreignColumn;
this.array = beanNode.array;
this.collection = beanNode.collection;
this.ignoreCase = beanNode.ignoreCase;
@@ -95,6 +222,19 @@ public class FilterBeanNode extends FilterNode {
}
}
@Override
protected <T> StringBuilder createFilterSQLExpress(final EntityInfo<T> info, FilterBean bean) {
if (joinSQL == null) return super.createFilterSQLExpress(info, bean);
StringBuilder sb = super.createFilterSQLExpress(info, bean);
String jsql = joinSQL.replace("#", info.getPrimarySQLColumn());
return new StringBuilder(sb.length() + jsql.length()).append(jsql).append(sb);
}
@Override
protected boolean isJoinAllCached() {
return false && joinallcached; //暂时没实现
}
@Override
protected Serializable getValue(FilterBean bean) {
if (bean == null || beanAttribute == null) return null;

View File

@@ -20,6 +20,8 @@ public class FilterNode {
protected boolean signand = true;
protected String tabalis;
protected String column;
protected FilterExpress express;
@@ -96,6 +98,7 @@ public class FilterNode {
newnode.signand = this.signand;
newnode.nodes = this.nodes;
this.nodes = new FilterNode[]{newnode};
this.tabalis = node.tabalis;
this.column = node.column;
this.express = node.express;
this.signand = sign;
@@ -106,6 +109,10 @@ public class FilterNode {
return value;
}
protected boolean isJoinAllCached() {
return true;
}
public static FilterNode create(String column, Serializable value) {
return create(column, FilterExpress.EQUAL, value);
}
@@ -114,13 +121,16 @@ public class FilterNode {
return new FilterNode(column, express, value);
}
protected final <T> StringBuilder createFilterSQLExpress(final EntityInfo<T> info, FilterBean bean) {
protected <T> StringBuilder createFilterSQLExpress(final EntityInfo<T> info, FilterBean bean) {
final Serializable val = getValue(bean);
if (val == null && express != ISNULL && express != ISNOTNULL) return null;
if (val == null && express != ISNULL && express != ISNOTNULL) return new StringBuilder(0);
StringBuilder sb0 = createFilterSQLExpress(info, val);
if (nodes == null) return sb0;
if (nodes == null) {
if (sb0 == null) return new StringBuilder(0);
return new StringBuilder(sb0.length() + 8).append(" WHERE ").append(sb0);
}
final StringBuilder rs = new StringBuilder();
rs.append('(');
rs.append(" WHERE (");
if (sb0 != null) rs.append(sb0);
for (FilterNode node : this.nodes) {
StringBuilder f = node.createFilterSQLExpress(info, bean);
@@ -129,7 +139,7 @@ public class FilterNode {
rs.append(f);
}
rs.append(')');
if (rs.length() < 3) return null;
if (rs.length() < 10) return new StringBuilder(0);
return rs;
}
@@ -137,6 +147,7 @@ public class FilterNode {
final StringBuilder val = formatValue(val0);
if (val == null) return null;
StringBuilder sb = new StringBuilder();
if (tabalis != null) sb.append(tabalis).append('.');
sb.append(info.getSQLColumn(column)).append(' ');
switch (express) {
case ISNULL:
@@ -261,7 +272,30 @@ public class FilterNode {
return null;
}
protected static <E> Comparator<E> getSortComparator(EntityInfo<E> info, Flipper flipper) {
protected static <E> StringBuilder createFilterSQLOrderBy(EntityInfo<E> info, Flipper flipper) {
if (flipper == null || flipper.getSort() == null || flipper.getSort().isEmpty()) return null;
final StringBuilder sb = new StringBuilder();
sb.append(" ORDER BY ");
if (info.isNoAlias()) {
sb.append(flipper.getSort());
} else {
boolean flag = false;
for (String item : flipper.getSort().split(",")) {
if (item.isEmpty()) continue;
String[] sub = item.split("\\s+");
if (flag) sb.append(',');
if (sub.length < 2 || sub[1].equalsIgnoreCase("ASC")) {
sb.append("a.").append(info.getSQLColumn(sub[0])).append(" ASC");
} else {
sb.append("a.").append(info.getSQLColumn(sub[0])).append(" DESC");
}
flag = true;
}
}
return sb;
}
protected static <E> Comparator<E> createFilterComparator(EntityInfo<E> info, Flipper flipper) {
if (flipper == null || flipper.getSort() == null || flipper.getSort().isEmpty()) return null;
Comparator<E> comparator = null;
for (String item : flipper.getSort().split(",")) {
@@ -371,6 +405,14 @@ public class FilterNode {
this.signand = signand;
}
public String getTabalis() {
return tabalis;
}
public void setTabalis(String tabalis) {
this.tabalis = tabalis;
}
public String getColumn() {
return column;
}