This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user