This commit is contained in:
地平线
2015-06-01 11:50:01 +08:00
parent 330876f97f
commit 2e1380f2c2
6 changed files with 69 additions and 49 deletions

View File

@@ -114,8 +114,8 @@ public final class DataJDBCSource implements DataSource {
public DataJDBCSource(final String unitName) throws IOException {
this(unitName, System.getProperty(DATASOURCE_CONFPATH) == null
? DataJDBCSource.class.getResource("/META-INF/persistence.xml")
: new File(System.getProperty(DATASOURCE_CONFPATH)).toURI().toURL());
? DataJDBCSource.class.getResource("/META-INF/persistence.xml")
: new File(System.getProperty(DATASOURCE_CONFPATH)).toURI().toURL());
}
public DataJDBCSource(final String unitName, URL url) throws IOException {
@@ -232,7 +232,7 @@ public final class DataJDBCSource implements DataSource {
static ConnectionPoolDataSource createDataSource(Properties property) {
try {
return createDataSource(property.getProperty(JDBC_SOURCE, property.getProperty(JDBC_DRIVER)),
property.getProperty(JDBC_URL), property.getProperty(JDBC_USER), property.getProperty(JDBC_PWD));
property.getProperty(JDBC_URL), property.getProperty(JDBC_USER), property.getProperty(JDBC_PWD));
} catch (Exception ex) {
throw new RuntimeException("(" + property + ") have no jdbc parameters", ex);
}
@@ -335,6 +335,10 @@ public final class DataJDBCSource implements DataSource {
return EntityInfo.load(clazz, this.nodeid, fullloader);
}
private <T extends FilterBean> FilterBeanNode loadFilterBeanNode(Class<T> clazz) {
return FilterBeanNode.load(clazz, this.nodeid, fullloader);
}
/**
* 将entity的对象全部加载到Cache中去如果clazz没有被@javax.persistence.Cacheable注解则不做任何事
* <p>
@@ -387,7 +391,7 @@ public final class DataJDBCSource implements DataSource {
final String sql = info.insertSQL;
if (debug.get()) logger.finest(clazz.getSimpleName() + " insert sql=" + sql);
final PreparedStatement prestmt = info.autoGenerated
? conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS) : conn.prepareStatement(sql);
? conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS) : conn.prepareStatement(sql);
final Class primaryType = info.getPrimary().type();
final Attribute primary = info.getPrimary();
final boolean distributed = info.distributed;
@@ -560,7 +564,7 @@ public final class DataJDBCSource implements DataSource {
try {
final EntityInfo<T> info = loadEntityInfo(clazz);
String sql = "DELETE FROM " + info.getTable() + " WHERE " + info.getPrimarySQLColumn()
+ " IN " + formatToString(keys);
+ " IN " + formatToString(keys);
if (debug.get()) logger.finest(clazz.getSimpleName() + " delete sql=" + sql);
final Statement stmt = conn.createStatement();
stmt.execute(sql);
@@ -649,6 +653,7 @@ public final class DataJDBCSource implements DataSource {
Class clazz = values[0].getClass();
final EntityInfo<T> info = loadEntityInfo(clazz);
if (debug.get()) logger.finest(clazz.getSimpleName() + " update sql=" + info.updateSQL);
final Attribute<T, Serializable> primary = info.getPrimary();
final PreparedStatement prestmt = conn.prepareStatement(info.updateSQL);
Attribute<T, Serializable>[] attrs = info.updateAttributes;
String[] sqls = null;
@@ -658,6 +663,7 @@ public final class DataJDBCSource implements DataSource {
for (Attribute<T, Serializable> attr : attrs) {
prestmt.setObject(++i, attr.get(value));
}
prestmt.setObject(++i, primary.get(value));
prestmt.addBatch();
}
} else {
@@ -672,6 +678,7 @@ public final class DataJDBCSource implements DataSource {
ps[i] = formatToString(a);
prestmt.setObject(++i, a);
}
prestmt.setObject(++i, primary.get(value));
prestmt.addBatch();
//-----------------------------
StringBuilder sb = new StringBuilder(128);
@@ -729,7 +736,7 @@ public final class DataJDBCSource implements DataSource {
try {
final EntityInfo<T> info = loadEntityInfo(clazz);
String sql = "UPDATE " + info.getTable() + " SET " + info.getSQLColumn(column) + " = "
+ formatToString(value) + " WHERE " + info.getPrimarySQLColumn() + " = " + formatToString(id);
+ formatToString(value) + " WHERE " + info.getPrimarySQLColumn() + " = " + formatToString(id);
if (debug.get()) logger.finest(clazz.getSimpleName() + " update sql=" + sql);
final Statement stmt = conn.createStatement();
stmt.execute(sql);
@@ -776,7 +783,7 @@ public final class DataJDBCSource implements DataSource {
final EntityInfo<T> info = loadEntityInfo(clazz);
String col = info.getSQLColumn(column);
String sql = "UPDATE " + info.getTable() + " SET " + col + " = " + col + " + (" + incvalue
+ ") WHERE " + info.getPrimarySQLColumn() + " = " + formatToString(id);
+ ") WHERE " + info.getPrimarySQLColumn() + " = " + formatToString(id);
if (debug.get()) logger.finest(clazz.getSimpleName() + " update sql=" + sql);
final Statement stmt = conn.createStatement();
stmt.execute(sql);
@@ -832,7 +839,7 @@ public final class DataJDBCSource implements DataSource {
setsql.append(info.getSQLColumn(col)).append(" = ").append(formatToString(attr.get(value)));
}
String sql = "UPDATE " + info.getTable() + " SET " + setsql
+ " WHERE " + info.getPrimarySQLColumn() + " = " + formatToString(id);
+ " WHERE " + info.getPrimarySQLColumn() + " = " + formatToString(id);
if (debug.get()) logger.finest(value.getClass().getSimpleName() + ": " + sql);
final Statement stmt = conn.createStatement();
stmt.execute(sql);
@@ -970,6 +977,7 @@ public final class DataJDBCSource implements DataSource {
final Connection conn = createReadSQLConnection();
try {
final EntityInfo<T> info = loadEntityInfo(entityClass);
if (node == null && bean != null) node = loadFilterBeanNode(bean.getClass());
final EntityCache<T> cache = info.getCache();
if (cache != null && cache.isFullLoaded()) {
Predicate<T> filter = node == null ? null : node.createFilterPredicate(info, bean);
@@ -978,7 +986,7 @@ public final class DataJDBCSource implements DataSource {
}
}
final String sql = "SELECT " + type.getReckonColumn("a." + column) + " FROM " + info.getTable() + " a"
+ (node == null ? "" : node.createFilterSQLExpress(info, bean));
+ (node == null ? "" : node.createFilterSQLExpress(info, bean));
if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(entityClass.getSimpleName() + " single sql=" + sql);
final PreparedStatement prestmt = conn.prepareStatement(sql);
Number rs = null;
@@ -1192,9 +1200,10 @@ public final class DataJDBCSource implements DataSource {
return querySheet(true, clazz, selects, flipper, node, null);
}
private <T> Sheet<T> querySheet(boolean readcache, Class<T> clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node, final FilterBean bean) {
private <T> Sheet<T> querySheet(boolean readcache, Class<T> clazz, final SelectColumn selects, final Flipper flipper, FilterNode node, final FilterBean bean) {
final EntityInfo<T> info = loadEntityInfo(clazz);
final EntityCache<T> cache = info.getCache();
if (node == null && bean != null) node = loadFilterBeanNode(bean.getClass());
if (readcache && cache != null) {
Predicate<T> filter = node == null ? null : node.createFilterPredicate(info, bean);
if (node == null || node.isJoinAllCached()) {
@@ -1207,7 +1216,7 @@ public final class DataJDBCSource implements DataSource {
final SelectColumn sels = selects;
final List<T> list = new ArrayList();
final String sql = "SELECT a.* FROM " + info.getTable() + " a"
+ (node == null ? "" : node.createFilterSQLExpress(info, bean)) + createFilterSQLOrderBy(info, flipper);
+ (node == null ? "" : node.createFilterSQLExpress(info, bean)) + createFilterSQLOrderBy(info, flipper);
if (debug.get() && info.isLoggable(Level.FINEST))
logger.finest(clazz.getSimpleName() + " query sql=" + sql + (flipper == null ? "" : (" LIMIT " + flipper.index() + "," + flipper.getSize())));
final PreparedStatement ps = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

View File

@@ -43,7 +43,7 @@ final class EntityCache<T> {
private boolean fullloaded;
public EntityCache(final Class<T> type, Creator<T> creator, Attribute<T, Serializable> primary,
Map<String, Attribute<T, Serializable>> attributes, Function<Class<T>, List<T>> fullloader) {
Map<String, Attribute<T, Serializable>> attributes) {
this.type = type;
this.creator = creator;
this.primary = primary;
@@ -58,11 +58,7 @@ final class EntityCache<T> {
} catch (Exception e) {
return false;
}
});
AutoLoad auto = type.getAnnotation(AutoLoad.class);
if (auto != null && auto.value() && fullloader != null) {
fullLoad(fullloader.apply(type));
}
});
}
public void fullLoad(List<T> all) {

View File

@@ -87,7 +87,7 @@ public final class EntityInfo<T> {
//------------------------------------------------------------
public static <T> EntityInfo<T> load(Class<T> clazz, final int nodeid,
Function<Class, List> fullloader) {
Function<Class, List> fullloader) {
EntityInfo rs = entityInfos.get(clazz);
if (rs != null) return rs;
synchronized (entityInfos) {
@@ -95,6 +95,10 @@ public final class EntityInfo<T> {
if (rs == null) {
rs = new EntityInfo(clazz, nodeid, fullloader);
entityInfos.put(clazz, rs);
AutoLoad auto = clazz.getAnnotation(AutoLoad.class);
if (rs.cache != null && auto != null && auto.value() && fullloader != null) {
rs.cache.fullLoad(fullloader.apply(clazz));
}
}
return rs;
}
@@ -211,7 +215,7 @@ public final class EntityInfo<T> {
Cacheable c = type.getAnnotation(Cacheable.class);
boolean cf = (c == null && cacheClasses != null && cacheClasses.contains(type));
if ((c != null && c.value()) || cf) {
this.cache = new EntityCache<>(type, creator, primary, attributes, fullloader);
this.cache = new EntityCache<>(type, creator, primary, attributes);
} else {
this.cache = null;
}
@@ -282,12 +286,13 @@ public final class EntityInfo<T> {
if (sels == null || sels.validate(attr.field())) {
Serializable o = (Serializable) set.getObject(this.getSQLColumn(attr.field()));
if (o != null) {
if (type == long.class) {
o = ((Number) o).longValue();
} else if (type == int.class) {
o = ((Number) o).intValue();
} else if (type == short.class) {
Class t = attr.type();
if (t == short.class) {
o = ((Number) o).shortValue();
} else if (t == long.class) {
o = ((Number) o).longValue();
} else if (t == int.class) {
o = ((Number) o).intValue();
}
}
attr.set(obj, o);

View File

@@ -27,7 +27,7 @@ final class FilterBeanNode extends FilterNode {
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) {
Function<Class, List> fullloader) {
FilterBeanNode rs = beanodes.get(clazz);
if (rs != null) return rs;
synchronized (beanodes) {
@@ -41,7 +41,7 @@ final class FilterBeanNode extends FilterNode {
}
private static <T extends FilterBean> FilterBeanNode createNode(Class<T> clazz, final int nodeid,
Function<Class, List> fullloader) {
Function<Class, List> fullloader) {
Class cltmp = clazz;
Set<String> fields = new HashSet<>();
final Map<Class, String> joinTables = new HashMap<>();
@@ -58,7 +58,7 @@ final class FilterBeanNode extends FilterNode {
char[] chars = field.getName().toCharArray();
chars[0] = Character.toUpperCase(chars[0]);
final Class t = field.getType();
Method getter = null;
Method getter;
try {
getter = cltmp.getMethod(((t == boolean.class || t == Boolean.class) ? "is" : "get") + new String(chars));
} catch (Exception ex) {
@@ -84,8 +84,8 @@ final class FilterBeanNode extends FilterNode {
}
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()));
.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;
@@ -108,7 +108,7 @@ final class FilterBeanNode extends FilterNode {
if (node == null) {
nodemap.put(key, newnode);
} else {
node.any(node, !key.contains("[OR]"));
node.any(newnode, !key.contains("[OR]"));
}
}
}
@@ -170,7 +170,7 @@ final class FilterBeanNode extends FilterNode {
this.least = fc == null ? 1L : fc.least();
this.likefit = fc == null ? true : fc.likefit();
this.ignoreCase = fc == null ? true : fc.ignoreCase();
this.number = type.isPrimitive() || Number.class.isAssignableFrom(type);
this.number = (type.isPrimitive() && type != boolean.class) || Number.class.isAssignableFrom(type);
this.string = CharSequence.class.isAssignableFrom(type);
FilterExpress exp = fc == null ? null : fc.express();
@@ -223,9 +223,9 @@ final 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);
protected <T> StringBuilder createFilterSQLExpress(final boolean first, final EntityInfo<T> info, FilterBean bean) {
if (joinSQL == null || !first) return super.createFilterSQLExpress(first, info, bean);
StringBuilder sb = super.createFilterSQLExpress(first, info, bean);
String jsql = joinSQL.replace("#", info.getPrimarySQLColumn());
return new StringBuilder(sb.length() + jsql.length()).append(jsql).append(sb);
}

View File

@@ -121,25 +121,35 @@ public class FilterNode {
return new FilterNode(column, express, value);
}
protected <T> StringBuilder createFilterSQLExpress(final EntityInfo<T> info, FilterBean bean) {
protected final <T> StringBuilder createFilterSQLExpress(final EntityInfo<T> info, FilterBean bean) {
return createFilterSQLExpress(true, info, bean);
}
protected <T> StringBuilder createFilterSQLExpress(final boolean first, final EntityInfo<T> info, FilterBean bean) {
final Serializable val = getValue(bean);
if (val == null && express != ISNULL && express != ISNOTNULL) return new StringBuilder(0);
if (val == null && (express == ISNULL || express == ISNOTNULL)) return new StringBuilder(0);
StringBuilder sb0 = createFilterSQLExpress(info, val);
if (nodes == null) {
if (this.nodes == null) {
if (sb0 == null) return new StringBuilder(0);
if (!first) return sb0;
return new StringBuilder(sb0.length() + 8).append(" WHERE ").append(sb0);
}
final StringBuilder rs = new StringBuilder();
rs.append(" WHERE (");
if (sb0 != null) rs.append(sb0);
rs.append(first ? " WHERE (" : " (");
boolean more = false;
if (sb0 != null && sb0.length() > 2) {
more = true;
rs.append(sb0);
}
for (FilterNode node : this.nodes) {
StringBuilder f = node.createFilterSQLExpress(info, bean);
if (f == null) continue;
if (rs.length() > 0) rs.append(signand ? " AND " : " OR ");
StringBuilder f = node.createFilterSQLExpress(false, info, bean);
if (f == null || f.length() < 3) continue;
if (more) rs.append(signand ? " AND " : " OR ");
rs.append(f);
more = true;
}
rs.append(')');
if (rs.length() < 10) return new StringBuilder(0);
if (rs.length() < (first ? 10 : 5)) return new StringBuilder(0);
return rs;
}
@@ -179,10 +189,10 @@ public class FilterNode {
break;
case OPAND:
case OPOR:
sb.append(express.value()).append(' ').append(val).append(" > 0)");
sb.append(express.value()).append(' ').append(val).append(" > 0");
break;
case OPANDNO:
sb.append(express.value()).append(' ').append(val).append(" = 0)");
sb.append(express.value()).append(' ').append(val).append(" = 0");
break;
default:
sb.append(express.value()).append(' ').append(val);
@@ -333,7 +343,7 @@ public class FilterNode {
if (value instanceof Number) return new StringBuilder().append(value);
if (value instanceof CharSequence) {
if (express == LIKE || express == NOTLIKE) value = "%" + value + '%';
return new StringBuilder().append('\\').append(value.toString().replace("'", "\\'")).append('\'');
return new StringBuilder().append('\'').append(value.toString().replace("'", "\\'")).append('\'');
} else if (value instanceof Range) {
Range range = (Range) value;
boolean rangestring = range.getClass() == Range.StringRange.class;
@@ -361,7 +371,7 @@ public class FilterNode {
sb.append('(');
for (int i = 0; i < len; i++) {
Object o = Array.get(value, i);
if (sb.length() > 0) sb.append(',');
if (sb.length() > 1) sb.append(',');
if (o instanceof CharSequence) {
sb.append('\'').append(o.toString().replace("'", "\\'")).append('\'');
} else {
@@ -375,7 +385,7 @@ public class FilterNode {
StringBuilder sb = new StringBuilder();
sb.append('(');
for (Object o : c) {
if (sb.length() > 0) sb.append(',');
if (sb.length() > 1) sb.append(',');
if (o instanceof CharSequence) {
sb.append('\'').append(o.toString().replace("'", "\\'")).append('\'');
} else {

View File

@@ -67,7 +67,7 @@ public interface Attribute<T, F> {
@SuppressWarnings("unchecked")
public static <T, F> Attribute<T, F> create(final Class<T> clazz, String fieldalias0, final Field field0, Method getter0, Method setter0) {
if (fieldalias0.isEmpty()) fieldalias0 = null;
if (fieldalias0 != null && fieldalias0.isEmpty()) fieldalias0 = null;
int mod = field0 == null ? Modifier.STATIC : field0.getModifiers();
if (field0 != null && !Modifier.isStatic(mod) && !Modifier.isPublic(mod)) {
Class t = field0.getType();