From 2e1380f2c2c5a12d09d29696e2afc4ec57d86ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9C=B0=E5=B9=B3=E7=BA=BF?= <22250530@qq.com> Date: Mon, 1 Jun 2015 11:50:01 +0800 Subject: [PATCH] --- .../wentch/redkale/source/DataJDBCSource.java | 31 +++++++++------ .../wentch/redkale/source/EntityCache.java | 8 +--- src/com/wentch/redkale/source/EntityInfo.java | 19 ++++++---- .../wentch/redkale/source/FilterBeanNode.java | 20 +++++----- src/com/wentch/redkale/source/FilterNode.java | 38 ++++++++++++------- src/com/wentch/redkale/util/Attribute.java | 2 +- 6 files changed, 69 insertions(+), 49 deletions(-) diff --git a/src/com/wentch/redkale/source/DataJDBCSource.java b/src/com/wentch/redkale/source/DataJDBCSource.java index c8edd37ef..39603d54d 100644 --- a/src/com/wentch/redkale/source/DataJDBCSource.java +++ b/src/com/wentch/redkale/source/DataJDBCSource.java @@ -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 FilterBeanNode loadFilterBeanNode(Class clazz) { + return FilterBeanNode.load(clazz, this.nodeid, fullloader); + } + /** * 将entity的对象全部加载到Cache中去,如果clazz没有被@javax.persistence.Cacheable注解则不做任何事 *

@@ -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 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 info = loadEntityInfo(clazz); if (debug.get()) logger.finest(clazz.getSimpleName() + " update sql=" + info.updateSQL); + final Attribute primary = info.getPrimary(); final PreparedStatement prestmt = conn.prepareStatement(info.updateSQL); Attribute[] attrs = info.updateAttributes; String[] sqls = null; @@ -658,6 +663,7 @@ public final class DataJDBCSource implements DataSource { for (Attribute 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 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 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 info = loadEntityInfo(entityClass); + if (node == null && bean != null) node = loadFilterBeanNode(bean.getClass()); final EntityCache cache = info.getCache(); if (cache != null && cache.isFullLoaded()) { Predicate 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 Sheet querySheet(boolean readcache, Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node, final FilterBean bean) { + private Sheet querySheet(boolean readcache, Class clazz, final SelectColumn selects, final Flipper flipper, FilterNode node, final FilterBean bean) { final EntityInfo info = loadEntityInfo(clazz); final EntityCache cache = info.getCache(); + if (node == null && bean != null) node = loadFilterBeanNode(bean.getClass()); if (readcache && cache != null) { Predicate 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 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); diff --git a/src/com/wentch/redkale/source/EntityCache.java b/src/com/wentch/redkale/source/EntityCache.java index c29c9ced7..3c76da9e3 100644 --- a/src/com/wentch/redkale/source/EntityCache.java +++ b/src/com/wentch/redkale/source/EntityCache.java @@ -43,7 +43,7 @@ final class EntityCache { private boolean fullloaded; public EntityCache(final Class type, Creator creator, Attribute primary, - Map> attributes, Function, List> fullloader) { + Map> attributes) { this.type = type; this.creator = creator; this.primary = primary; @@ -58,11 +58,7 @@ final class EntityCache { } 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 all) { diff --git a/src/com/wentch/redkale/source/EntityInfo.java b/src/com/wentch/redkale/source/EntityInfo.java index c25b3e095..3721c3e5c 100644 --- a/src/com/wentch/redkale/source/EntityInfo.java +++ b/src/com/wentch/redkale/source/EntityInfo.java @@ -87,7 +87,7 @@ public final class EntityInfo { //------------------------------------------------------------ public static EntityInfo load(Class clazz, final int nodeid, - Function fullloader) { + Function fullloader) { EntityInfo rs = entityInfos.get(clazz); if (rs != null) return rs; synchronized (entityInfos) { @@ -95,6 +95,10 @@ public final class EntityInfo { 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 { 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 { 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); diff --git a/src/com/wentch/redkale/source/FilterBeanNode.java b/src/com/wentch/redkale/source/FilterBeanNode.java index 3b249d9ec..950f00186 100644 --- a/src/com/wentch/redkale/source/FilterBeanNode.java +++ b/src/com/wentch/redkale/source/FilterBeanNode.java @@ -27,7 +27,7 @@ final class FilterBeanNode extends FilterNode { private static final ConcurrentHashMap beanodes = new ConcurrentHashMap<>(); public static FilterBeanNode load(Class clazz, final int nodeid, - Function fullloader) { + Function fullloader) { FilterBeanNode rs = beanodes.get(clazz); if (rs != null) return rs; synchronized (beanodes) { @@ -41,7 +41,7 @@ final class FilterBeanNode extends FilterNode { } private static FilterBeanNode createNode(Class clazz, final int nodeid, - Function fullloader) { + Function fullloader) { Class cltmp = clazz; Set fields = new HashSet<>(); final Map 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 StringBuilder createFilterSQLExpress(final EntityInfo info, FilterBean bean) { - if (joinSQL == null) return super.createFilterSQLExpress(info, bean); - StringBuilder sb = super.createFilterSQLExpress(info, bean); + protected StringBuilder createFilterSQLExpress(final boolean first, final EntityInfo 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); } diff --git a/src/com/wentch/redkale/source/FilterNode.java b/src/com/wentch/redkale/source/FilterNode.java index d5ad4900c..a5c89fdcd 100644 --- a/src/com/wentch/redkale/source/FilterNode.java +++ b/src/com/wentch/redkale/source/FilterNode.java @@ -121,25 +121,35 @@ public class FilterNode { return new FilterNode(column, express, value); } - protected StringBuilder createFilterSQLExpress(final EntityInfo info, FilterBean bean) { + protected final StringBuilder createFilterSQLExpress(final EntityInfo info, FilterBean bean) { + return createFilterSQLExpress(true, info, bean); + } + + protected StringBuilder createFilterSQLExpress(final boolean first, final EntityInfo 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 { diff --git a/src/com/wentch/redkale/util/Attribute.java b/src/com/wentch/redkale/util/Attribute.java index 86b0c34a3..d4429c8d6 100644 --- a/src/com/wentch/redkale/util/Attribute.java +++ b/src/com/wentch/redkale/util/Attribute.java @@ -67,7 +67,7 @@ public interface Attribute { @SuppressWarnings("unchecked") public static Attribute create(final Class 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();