diff --git a/src/com/wentch/redkale/source/DataJDBCSource.java b/src/com/wentch/redkale/source/DataJDBCSource.java index 131cd0453..b6a2a9634 100644 --- a/src/com/wentch/redkale/source/DataJDBCSource.java +++ b/src/com/wentch/redkale/source/DataJDBCSource.java @@ -65,7 +65,7 @@ public final class DataJDBCSource implements DataSource { final List cacheClasses = new ArrayList<>(); @Resource(name = "property.datasource.nodeid") - private int nodeid; + int nodeid; @Resource DataSQLListener writeListener; @@ -122,8 +122,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 { @@ -240,7 +240,7 @@ public final class DataJDBCSource implements DataSource { private 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); } @@ -339,6 +339,10 @@ public final class DataJDBCSource implements DataSource { } } + private EntityInfo loadEntityInfo(Class clazz) { + return EntityInfo.load(clazz, this); + } + /** * 将entity的对象全部加载到Cache中去,如果clazz没有被@javax.persistence.Cacheable注解则不做任何事 *

@@ -386,16 +390,16 @@ public final class DataJDBCSource implements DataSource { if (values.length == 0) return; try { final Class clazz = (Class) values[0].getClass(); - final EntityXInfo info = EntityXInfo.load(this, clazz); - final EntityCache cache = info.inner.getCache(); - final String sql = info.insert.sql; + final EntityInfo info = loadEntityInfo(clazz); + final EntityCache cache = info.getCache(); + 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); - final Class primaryType = info.getPrimaryType(); + ? 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; - Attribute[] attrs = info.insert.attributes; + Attribute[] attrs = info.insertAttributes; String[] sqls = null; if (distributed && !info.initedPrimaryValue && primaryType.isPrimitive()) { synchronized (info) { @@ -415,7 +419,7 @@ public final class DataJDBCSource implements DataSource { stmt.close(); if (info.distributeTables != null) { for (final Class t : info.distributeTables) { - EntityXInfo infox = EntityXInfo.load(this, t); + EntityInfo infox = loadEntityInfo(t); stmt = conn.createStatement(); rs = stmt.executeQuery("SELECT MAX(" + infox.getPrimarySQLColumn() + ") FROM " + infox.getTable()); if (rs.next()) { @@ -501,8 +505,8 @@ public final class DataJDBCSource implements DataSource { public void insertCache(T... values) { if (values.length == 0) return; - final EntityXInfo info = EntityXInfo.load(this, (Class) values[0].getClass()); - final EntityCache cache = info.inner.getCache(); + final EntityInfo info = EntityInfo.load((Class) values[0].getClass(), this); + final EntityCache cache = info.getCache(); if (cache == null) return; for (T value : values) { cache.insert(value); @@ -541,8 +545,8 @@ public final class DataJDBCSource implements DataSource { private void delete(final Connection conn, T... values) { if (values.length == 0) return; final Class clazz = values[0].getClass(); - final EntityXInfo info = EntityXInfo.load(this, clazz); - final Attribute primary = info.inner.getPrimary(); + final EntityInfo info = loadEntityInfo(clazz); + final Attribute primary = info.getPrimary(); Serializable[] ids = new Serializable[values.length]; int i = 0; for (final T value : values) { @@ -556,7 +560,7 @@ public final class DataJDBCSource implements DataSource { * * @param * @param clazz - * @param ids 主键值 + * @param ids 主键值 */ @Override public void delete(Class clazz, Serializable... ids) { @@ -582,7 +586,7 @@ public final class DataJDBCSource implements DataSource { } private void delete(final Connection conn, Class clazz, Serializable... ids) { - deleteByColumn(conn, clazz, EntityXInfo.load(this, clazz).getPrimaryField(), ids); + deleteByColumn(conn, clazz, loadEntityInfo(clazz).getPrimary().field(), ids); } /** @@ -620,7 +624,7 @@ public final class DataJDBCSource implements DataSource { private void deleteByColumn(final Connection conn, Class clazz, String column, Serializable... keys) { if (keys.length == 0) return; try { - final EntityXInfo info = EntityXInfo.load(this, clazz); + final EntityInfo info = loadEntityInfo(clazz); String sql = "DELETE FROM " + info.getTable() + " WHERE " + info.getSQLColumn(column); if (keys.length == 1 && !keys[0].getClass().isArray()) { sql += " = " + formatToString(keys[0]); @@ -653,7 +657,7 @@ public final class DataJDBCSource implements DataSource { stmt.close(); if (writeListener != null) writeListener.delete(name, sql); //------------------------------------ - final EntityCache cache = info.inner.getCache(); + final EntityCache cache = info.getCache(); if (cache == null) return; final Attribute attr = info.getAttribute(column); final Serializable[] keys2 = keys; @@ -702,16 +706,16 @@ public final class DataJDBCSource implements DataSource { private void deleteByTwoColumn(final Connection conn, Class clazz, String column1, Serializable key1, String column2, Serializable key2) { try { - final EntityXInfo info = EntityXInfo.load(this, clazz); + final EntityInfo info = loadEntityInfo(clazz); String sql = "DELETE FROM " + info.getTable() + " WHERE " + info.getSQLColumn(column1) + " = " + formatToString(key1) - + " AND " + info.getSQLColumn(column2) + " = " + formatToString(key2); + + " AND " + info.getSQLColumn(column2) + " = " + formatToString(key2); if (debug.get()) logger.finest(clazz.getSimpleName() + " delete sql=" + sql); final Statement stmt = conn.createStatement(); stmt.execute(sql); stmt.close(); if (writeListener != null) writeListener.delete(name, sql); //------------------------------------ - final EntityCache cache = info.inner.getCache(); + final EntityCache cache = info.getCache(); if (cache == null) return; final Attribute attr1 = info.getAttribute(column1); final Attribute attr2 = info.getAttribute(column2); @@ -724,8 +728,8 @@ public final class DataJDBCSource implements DataSource { public void deleteCache(Class clazz, Serializable... ids) { if (ids.length == 0) return; - final EntityXInfo info = EntityXInfo.load(this, clazz); - final EntityCache cache = info.inner.getCache(); + final EntityInfo info = loadEntityInfo(clazz); + final EntityCache cache = info.getCache(); if (cache == null) return; for (Serializable id : ids) { cache.delete(id); @@ -764,10 +768,10 @@ public final class DataJDBCSource implements DataSource { private void update(final Connection conn, T... values) { try { Class clazz = values[0].getClass(); - final EntityXInfo info = EntityXInfo.load(this, clazz); - if (debug.get()) logger.finest(clazz.getSimpleName() + " update sql=" + info.update.sql); - final PreparedStatement prestmt = conn.prepareStatement(info.update.sql); - Attribute[] attrs = info.update.attributes; + final EntityInfo info = loadEntityInfo(clazz); + if (debug.get()) logger.finest(clazz.getSimpleName() + " update sql=" + info.updateSQL); + final PreparedStatement prestmt = conn.prepareStatement(info.updateSQL); + Attribute[] attrs = info.updateAttributes; String[] sqls = null; if (writeListener == null) { for (final T value : values) { @@ -778,7 +782,7 @@ public final class DataJDBCSource implements DataSource { prestmt.addBatch(); } } else { - char[] sqlchars = info.update.sql.toCharArray(); + char[] sqlchars = info.updateSQL.toCharArray(); sqls = new String[values.length]; String[] ps = new String[attrs.length]; int index = 0; @@ -807,7 +811,7 @@ public final class DataJDBCSource implements DataSource { prestmt.close(); if (writeListener != null) writeListener.update(name, sqls); //--------------------------------------------------- - final EntityCache cache = info.inner.getCache(); + final EntityCache cache = info.getCache(); if (cache == null) return; for (final T value : values) { cache.update(value); @@ -854,7 +858,7 @@ public final class DataJDBCSource implements DataSource { private void updateColumn(Connection conn, Class clazz, Serializable id, String column, Serializable value) { try { - final EntityXInfo info = EntityXInfo.load(this, clazz); + final EntityInfo info = loadEntityInfo(clazz); String sql = "UPDATE " + info.getTable() + " SET " + info.getSQLColumn(column) + " = " + formatToString(value) + " WHERE " + info.getPrimarySQLColumn() + " = " + formatToString(id); if (debug.get()) logger.finest(clazz.getSimpleName() + " update sql=" + sql); final Statement stmt = conn.createStatement(); @@ -862,7 +866,7 @@ public final class DataJDBCSource implements DataSource { stmt.close(); if (writeListener != null) writeListener.update(name, sql); //--------------------------------------------------- - final EntityCache cache = info.inner.getCache(); + final EntityCache cache = info.getCache(); if (cache == null) return; T rs = cache.update(id, (Attribute) info.getAttribute(column), value); if (cacheListener != null) cacheListener.update(name, clazz, rs); @@ -909,7 +913,7 @@ public final class DataJDBCSource implements DataSource { private void updateColumnIncrement(Connection conn, Class clazz, Serializable id, String column, long incvalue) { try { - final EntityXInfo info = EntityXInfo.load(this, clazz); + final EntityInfo info = loadEntityInfo(clazz); String col = info.getSQLColumn(column); String sql = "UPDATE " + info.getTable() + " SET " + col + " = " + col + " + (" + incvalue + ") WHERE " + info.getPrimarySQLColumn() + " = " + formatToString(id); if (debug.get()) logger.finest(clazz.getSimpleName() + " update sql=" + sql); @@ -918,7 +922,7 @@ public final class DataJDBCSource implements DataSource { stmt.close(); if (writeListener != null) writeListener.update(name, sql); //--------------------------------------------------- - final EntityCache cache = info.inner.getCache(); + final EntityCache cache = info.getCache(); if (cache == null) return; Attribute attr = (Attribute) info.getAttribute(column); T value = cache.updateColumnIncrement(id, attr, incvalue); @@ -964,7 +968,7 @@ public final class DataJDBCSource implements DataSource { if (columns.length < 1) return; try { final Class clazz = (Class) value.getClass(); - final EntityXInfo info = EntityXInfo.load(this, clazz); + final EntityInfo info = loadEntityInfo(clazz); StringBuilder setsql = new StringBuilder(); Attribute[] attrs = new Attribute[columns.length]; int i = - 1; @@ -973,17 +977,17 @@ public final class DataJDBCSource implements DataSource { if (setsql.length() > 0) setsql.append(','); attrs[++i] = info.getAttribute(col); setsql.append(info.getSQLColumn(col)).append(" = ") - .append(formatToString(attrs[i].get(value))); + .append(formatToString(attrs[i].get(value))); } String sql = "UPDATE " + info.getTable() + " SET " + setsql + " WHERE " + info.getPrimarySQLColumn() + " = " - + formatToString(id); + + formatToString(id); if (debug.get()) logger.finest(value.getClass().getSimpleName() + ": " + sql); final Statement stmt = conn.createStatement(); stmt.execute(sql); stmt.close(); if (writeListener != null) writeListener.update(name, sql); //--------------------------------------------------- - final EntityCache cache = info.inner.getCache(); + final EntityCache cache = info.getCache(); if (cache == null) return; cache.update(value, attrs); if (cacheListener != null) cacheListener.update(name, clazz, value); @@ -994,8 +998,8 @@ public final class DataJDBCSource implements DataSource { public void updateCache(Class clazz, T... values) { if (values.length == 0) return; - final EntityXInfo info = EntityXInfo.load(this, clazz); - final EntityCache cache = info.inner.getCache(); + final EntityInfo info = loadEntityInfo(clazz); + final EntityCache cache = info.getCache(); if (cache == null) return; for (T value : values) { cache.update(value); @@ -1003,8 +1007,8 @@ public final class DataJDBCSource implements DataSource { } public void reloadCache(Class clazz, Serializable... ids) { - final EntityXInfo info = EntityXInfo.load(this, clazz); - final EntityCache cache = info.inner.getCache(); + final EntityInfo info = loadEntityInfo(clazz); + final EntityCache cache = info.getCache(); if (cache == null) return; for (Serializable id : ids) { T value = find(clazz, null, false, id); @@ -1081,15 +1085,15 @@ public final class DataJDBCSource implements DataSource { private Number getSingleResult(final ReckonType type, final Class entityClass, final String column, FilterBean bean) { final Connection conn = createReadSQLConnection(); try { - final EntityXInfo info = EntityXInfo.load(this, entityClass); - final EntityCache cache = info.inner.getCache(); + final EntityInfo info = loadEntityInfo(entityClass); + final EntityCache cache = info.getCache(); if (cache != null && cache.isFullLoaded()) { Predicate filter = null; boolean valid = true; if (bean != null) { FilterInfo finfo = FilterInfo.load(bean.getClass(), this); valid = finfo.isValidCacheJoin(); - if (valid) filter = finfo.getFilterPredicate(info.inner, bean); + if (valid) filter = finfo.getFilterPredicate(info, bean); } if (valid) return cache.getSingleResult(type, column == null ? null : info.getAttribute(column), filter); } @@ -1131,24 +1135,21 @@ public final class DataJDBCSource implements DataSource { } private T find(Class clazz, final SelectColumn selects, boolean readcache, Serializable pk) { - final EntityXInfo info = EntityXInfo.load(this, clazz); - final EntityCache cache = info.inner.getCache(); + final EntityInfo info = loadEntityInfo(clazz); + final EntityCache cache = info.getCache(); if (readcache && cache != null) { T r = cache.find(pk); if (r != null || cache.isFullLoaded()) return r; } final Connection conn = createReadSQLConnection(); try { - if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(clazz.getSimpleName() + " find sql=" + info.query.sql.replace("?", String.valueOf(pk))); - final PreparedStatement prestmt = conn.prepareStatement(info.query.sql); + if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(clazz.getSimpleName() + " find sql=" + info.querySQL.replace("?", String.valueOf(pk))); + final PreparedStatement prestmt = conn.prepareStatement(info.querySQL); prestmt.setObject(1, pk); T rs = null; ResultSet set = prestmt.executeQuery(); if (set.next()) { - rs = info.createInstance(); - for (AttributeX attr : info.query.attributes) { - attr.setValue(selects, rs, set); - } + rs = info.getValue(selects, set); } set.close(); prestmt.close(); @@ -1170,7 +1171,7 @@ public final class DataJDBCSource implements DataSource { */ @Override public T[] find(Class clazz, Serializable... ids) { - EntityXInfo info = EntityXInfo.load(this, clazz); + EntityInfo info = loadEntityInfo(clazz); return findByColumn(clazz, info, null, info.getPrimarySQLColumn(), ids); } @@ -1185,7 +1186,7 @@ public final class DataJDBCSource implements DataSource { */ @Override public T findByColumn(Class clazz, String column, Serializable key) { - EntityXInfo info = EntityXInfo.load(this, clazz); + EntityInfo info = loadEntityInfo(clazz); return findByColumn(clazz, info, null, info.getSQLColumn(column), key)[0]; } @@ -1202,8 +1203,8 @@ public final class DataJDBCSource implements DataSource { */ @Override public T findByTwoColumn(Class clazz, String column1, Serializable key1, String column2, Serializable key2) { - final EntityXInfo info = EntityXInfo.load(this, clazz); - final EntityCache cache = info.inner.getCache(); + final EntityInfo info = loadEntityInfo(clazz); + final EntityCache cache = info.getCache(); if (cache != null) { final Attribute attr1 = info.getAttribute(column1); final Attribute attr2 = info.getAttribute(column2); @@ -1213,17 +1214,15 @@ public final class DataJDBCSource implements DataSource { final Connection conn = createReadSQLConnection(); try { final String sql = "SELECT * FROM " + info.getTable() + " WHERE " + info.getSQLColumn(column1) + " = ? AND " + info.getSQLColumn(column2) + " = ?"; - if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(clazz.getSimpleName() + " find sql=" + sql.replaceFirst("\\?", String.valueOf(key1)).replaceFirst("\\?", String.valueOf(key2))); + if (debug.get() && info.isLoggable(Level.FINEST)) + logger.finest(clazz.getSimpleName() + " find sql=" + sql.replaceFirst("\\?", String.valueOf(key1)).replaceFirst("\\?", String.valueOf(key2))); final PreparedStatement prestmt = conn.prepareStatement(sql); prestmt.setObject(1, key1); prestmt.setObject(2, key2); T rs = null; ResultSet set = prestmt.executeQuery(); if (set.next()) { - rs = info.createInstance(); - for (AttributeX attr : info.query.attributes) { - attr.setValue(null, rs, set); - } + rs = info.getValue(null, set); } set.close(); prestmt.close(); @@ -1276,8 +1275,8 @@ public final class DataJDBCSource implements DataSource { @Override public T[] findByColumn(Class clazz, final SelectColumn selects, String column, Serializable... keys) { - final EntityXInfo info = EntityXInfo.load(this, clazz); - final EntityCache cache = info.inner.getCache(); + final EntityInfo info = loadEntityInfo(clazz); + final EntityCache cache = info.getCache(); if (cache != null) { Attribute idattr = info.getAttribute(column); List list = cache.queryList(selects, (x) -> Arrays.binarySearch(keys, idattr.get(x)) >= 0, null); @@ -1299,7 +1298,7 @@ public final class DataJDBCSource implements DataSource { return findByColumn(clazz, info, selects, info.getSQLColumn(column), keys); } - private T[] findByColumn(Class clazz, final EntityXInfo info, final SelectColumn selects, String sqlcolumn, Serializable... keys) { + private T[] findByColumn(Class clazz, final EntityInfo info, final SelectColumn selects, String sqlcolumn, Serializable... keys) { if (keys.length < 1) return (T[]) Array.newInstance(clazz, 0); final Connection conn = createReadSQLConnection(); try { @@ -1313,10 +1312,7 @@ public final class DataJDBCSource implements DataSource { T one = null; ResultSet set = prestmt.executeQuery(); if (set.next()) { - one = info.createInstance(); - for (AttributeX attr : info.query.attributes) { - attr.setValue(selects, one, set); - } + one = info.getValue(selects, set); } rs[i] = one; set.close(); @@ -1425,8 +1421,8 @@ public final class DataJDBCSource implements DataSource { * @return */ protected final Collection queryColumnCollection(final boolean set, String selectedColumn, Class clazz, String column, FilterExpress express, Serializable key) { - final EntityXInfo info = EntityXInfo.load(this, clazz); - final EntityCache cache = info.inner.getCache(); + final EntityInfo info = loadEntityInfo(clazz); + final EntityCache cache = info.getCache(); if (cache != null) { Predicate filter = genFilter(info.getAttribute(column), express, key); List list = cache.queryList(SelectColumn.createIncludes(selectedColumn), filter, null); @@ -1506,8 +1502,8 @@ public final class DataJDBCSource implements DataSource { */ @Override public List queryList(Class clazz, final SelectColumn selects, String column, FilterExpress express, Serializable key) { - final EntityXInfo info = EntityXInfo.load(this, clazz); - final EntityCache cache = info.inner.getCache(); + final EntityInfo info = loadEntityInfo(clazz); + final EntityCache cache = info.getCache(); if (cache != null) { Predicate filter = genFilter(info.getAttribute(column), express, key); List rs = cache.queryList(selects, filter, null); @@ -1522,11 +1518,7 @@ public final class DataJDBCSource implements DataSource { final Statement ps = conn.createStatement(); final ResultSet set = ps.executeQuery(sql); while (set.next()) { - final T result = info.createInstance(); - for (AttributeX attr : info.query.attributes) { - attr.setValue(sels, result, set); - } - list.add(result); + list.add(info.getValue(sels, set)); } set.close(); ps.close(); @@ -1538,7 +1530,7 @@ public final class DataJDBCSource implements DataSource { } } - private String genSQL(String queryColumn, EntityXInfo info, String column, FilterExpress express, Serializable key) { + private String genSQL(String queryColumn, EntityInfo info, String column, FilterExpress express, Serializable key) { String sql = "SELECT " + queryColumn + " FROM " + info.getTable(); if (key instanceof Number) { sql += " WHERE " + info.getSQLColumn(column) + " " + express.value() + " " + key; @@ -1710,7 +1702,7 @@ public final class DataJDBCSource implements DataSource { final Sheet rs = new Sheet<>(); if (sheet.isEmpty()) return rs; rs.setTotal(sheet.getTotal()); - final EntityXInfo info = EntityXInfo.load(this, clazz); + final EntityInfo info = loadEntityInfo(clazz); final Attribute selected = (Attribute) info.getAttribute(selectedColumn); final List list = new ArrayList<>(); for (T t : sheet.getRows()) { @@ -1746,18 +1738,18 @@ public final class DataJDBCSource implements DataSource { */ @Override public Sheet querySheet(Class clazz, final SelectColumn selects, final Flipper flipper, final FilterBean bean) { - final EntityXInfo info = EntityXInfo.load(this, clazz); - final EntityCache cache = info.inner.getCache(); + final EntityInfo info = loadEntityInfo(clazz); + final EntityCache cache = info.getCache(); if (cache != null) { Predicate filter = null; boolean valid = true; if (bean != null) { FilterInfo finfo = FilterInfo.load(bean.getClass(), this); valid = finfo.isValidCacheJoin(); - if (valid) filter = finfo.getFilterPredicate(info.inner, bean); + if (valid) filter = finfo.getFilterPredicate(info, bean); } if (valid) { - Sheet sheet = cache.querySheet(selects, filter, flipper, FilterInfo.getSortComparator(info.inner, flipper)); + Sheet sheet = cache.querySheet(selects, filter, flipper, FilterInfo.getSortComparator(info, flipper)); if (!sheet.isEmpty() || cache.isFullLoaded()) return sheet; } } @@ -1766,7 +1758,8 @@ public final class DataJDBCSource implements DataSource { final SelectColumn sels = selects; final List list = new ArrayList(); final String sql = "SELECT a.* FROM " + info.getTable() + " a" + createWhereExpression(info, flipper, bean); - if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(clazz.getSimpleName() + " query sql=" + sql + (flipper == null ? "" : (" LIMIT " + flipper.index() + "," + flipper.getSize()))); + 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); final ResultSet set = ps.executeQuery(); if (flipper != null && flipper.index() > 0) set.absolute(flipper.index()); @@ -1775,11 +1768,7 @@ public final class DataJDBCSource implements DataSource { long total; while (set.next()) { i++; - final T result = info.createInstance(); - for (AttributeX attr : info.query.attributes) { - attr.setValue(sels, result, set); - } - list.add(result); + list.add(info.getValue(sels, set)); if (limit <= i) break; } if (flipper != null) { @@ -1798,7 +1787,7 @@ public final class DataJDBCSource implements DataSource { } } - private String createWhereExpression(final EntityXInfo info, final Flipper flipper, final FilterBean bean) { + private String createWhereExpression(final EntityInfo info, final Flipper flipper, final FilterBean bean) { if (bean == null && flipper == null) return ""; boolean emptySort = flipper == null || flipper.getSort() == null || flipper.getSort().isEmpty(); StringBuilder where = null; @@ -1811,7 +1800,7 @@ public final class DataJDBCSource implements DataSource { if (emptySort) return where == null ? "" : where.toString(); if (where == null) where = new StringBuilder(); where.append(" ORDER BY "); - if (info.same && !join) { + if (info.isNoAlias() && !join) { where.append(flipper.getSort()); } else { boolean flag = false; @@ -2113,9 +2102,9 @@ public final class DataJDBCSource implements DataSource { } - private static class EntityXInfo { + private static class EntityXXInfo { - private static final ConcurrentHashMap entityxInfos = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap entityxInfos = new ConcurrentHashMap<>(); private final int nodeid; @@ -2163,7 +2152,7 @@ public final class DataJDBCSource implements DataSource { } } - public EntityXInfo(DataJDBCSource source, Class type) { + public EntityXXInfo(DataJDBCSource source, Class type) { this.inner = EntityInfo.load(type, source); this.nodeid = source.nodeid; DistributeTables dt = type.getAnnotation(DistributeTables.class); @@ -2233,7 +2222,7 @@ public final class DataJDBCSource implements DataSource { queryattrs.add(attr); } } while ((cltmp = cltmp.getSuperclass()) != Object.class); - AttributeX idxattr = new AttributeX(type, idfieldtype, inner.getPrimary(), inner.getPrimaryField()); + AttributeX idxattr = new AttributeX(type, idfieldtype, inner.getPrimary(), inner.getPrimary().field()); updateattrs.add(idxattr); this.autoGenerated = auto; this.delete = new ActionInfo("DELETE FROM " + inner.getTable() + wheresql, idxattr); @@ -2259,13 +2248,13 @@ public final class DataJDBCSource implements DataSource { this.query = new ActionInfo("SELECT * FROM " + inner.getTable() + wheresql, queryattrs); } - public static EntityXInfo load(DataJDBCSource source, Class clazz) { - EntityXInfo rs = entityxInfos.get(clazz); + public static EntityXXInfo load(DataJDBCSource source, Class clazz) { + EntityXXInfo rs = entityxInfos.get(clazz); if (rs != null) return rs; synchronized (entityxInfos) { rs = entityxInfos.get(clazz); if (rs == null) { - rs = new EntityXInfo(source, clazz); + rs = new EntityXXInfo(source, clazz); entityxInfos.put(clazz, rs); } return rs; @@ -2282,7 +2271,7 @@ public final class DataJDBCSource implements DataSource { public void createPrimaryValue(T src) { long v = allocationSize > 1 ? (primaryValue.incrementAndGet() * allocationSize + nodeid) : primaryValue.incrementAndGet(); - Class p = inner.getPrimaryType(); + Class p = inner.getPrimary().type(); if (p == int.class || p == Integer.class) { getPrimary().set(src, (Integer) ((Long) v).intValue()); } else { @@ -2290,18 +2279,10 @@ public final class DataJDBCSource implements DataSource { } } - public Class getPrimaryType() { - return inner.getPrimaryType(); - } - - public Attribute getPrimary() { + public Attribute getPrimary() { return inner.getPrimary(); } - public String getPrimaryField() { - return inner.getPrimaryField(); - } - public String getTable() { return inner.getTable(); } diff --git a/src/com/wentch/redkale/source/DataJPASource.java b/src/com/wentch/redkale/source/DataJPASource.java index 42a8b56de..4fd9f059e 100644 --- a/src/com/wentch/redkale/source/DataJPASource.java +++ b/src/com/wentch/redkale/source/DataJPASource.java @@ -519,7 +519,7 @@ final class DataJPASource implements DataSource { final CriteriaBuilder builder = manager.getCriteriaBuilder(); CriteriaUpdate cd = builder.createCriteriaUpdate(clazz); cd.set(column, value); - cd.where(builder.equal(cd.from(clazz).get(EntityInfo.load(clazz, this).getPrimaryField()), id)); + cd.where(builder.equal(cd.from(clazz).get(EntityInfo.load(clazz, this).getPrimary().field()), id)); manager.createQuery(cd).executeUpdate(); } @@ -565,7 +565,7 @@ final class DataJPASource implements DataSource { for (String column : columns) { cd.set(column, info.getAttribute(column).get(value)); } - cd.where(builder.equal(cd.from(clazz).get(info.getPrimaryField()), idattr.get(value))); + cd.where(builder.equal(cd.from(clazz).get(info.getPrimary().field()), idattr.get(value))); manager.createQuery(cd).executeUpdate(); } @@ -1037,7 +1037,7 @@ final class DataJPASource implements DataSource { private List selectList(final Class clazz, final SelectColumn selects, final List list) { if (selects == null || selects.isEmpty() || list.isEmpty()) return list; final EntityInfo info = EntityInfo.load(clazz, this); - final Object dftValue = info.getDefaultTypeInstance(); + final Object dftValue = info.getCreator().create(); final Map map = info.getAttributes(); final List attrs = new ArrayList<>(); if (selects.isExcludable()) { diff --git a/src/com/wentch/redkale/source/EntityCache.java b/src/com/wentch/redkale/source/EntityCache.java index 7476d14af..ff8c14a8f 100644 --- a/src/com/wentch/redkale/source/EntityCache.java +++ b/src/com/wentch/redkale/source/EntityCache.java @@ -5,10 +5,7 @@ */ package com.wentch.redkale.source; -import com.wentch.redkale.util.Sheet; -import com.wentch.redkale.util.Reproduce; -import com.wentch.redkale.util.Creator; -import com.wentch.redkale.util.Attribute; +import com.wentch.redkale.util.*; import java.io.*; import java.lang.reflect.Field; import java.util.*; @@ -36,8 +33,9 @@ final class EntityCache { private final Creator creator; - private final Attribute primary; + private final Attribute primary; + //key是field的name private final Map> attributes; private final Reproduce reproduce; @@ -45,7 +43,7 @@ final class EntityCache { private boolean fullloaded; public EntityCache(final Class type, Creator creator, - Attribute primary, Map> attributes) { + Attribute primary, Map> attributes) { this.type = type; this.creator = creator; this.primary = primary; diff --git a/src/com/wentch/redkale/source/EntityInfo.java b/src/com/wentch/redkale/source/EntityInfo.java index 5fb2f3646..76aa0bc9c 100644 --- a/src/com/wentch/redkale/source/EntityInfo.java +++ b/src/com/wentch/redkale/source/EntityInfo.java @@ -7,9 +7,12 @@ package com.wentch.redkale.source; import com.sun.istack.internal.logging.Logger; import com.wentch.redkale.util.*; +import java.io.Serializable; import java.lang.reflect.*; +import java.sql.*; import java.util.*; import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicLong; import java.util.logging.*; import javax.persistence.*; @@ -25,32 +28,66 @@ public final class EntityInfo { private static final Logger logger = Logger.getLogger(EntityInfo.class); + //Entity类的类名 private final Class type; + //类对应的数据表名 private final String table; private final Creator creator; - private final Class primaryType; - - private final Attribute primary; - - private final String primaryFieldName; - - private final T defaultTypeInstance; + //主键 + private final Attribute primary; private final EntityCache cache; + //key是field的name, value是Column的别名,即数据库表的字段名 + //只有field.name 与 Column.name不同才存放在aliasmap里. + private final Map aliasmap; + + //key是field的name, 不是sql字段。 + //存放所有与数据库对应的字段, 包括主键 private final Map> attributes = new HashMap<>(); + final String querySQL; + + private final Attribute[] queryAttributes; //数据库中所有字段 + + final String insertSQL; + + final Attribute[] insertAttributes; //数据库中所有可新增字段 + + final String updateSQL; + + final Attribute[] updateAttributes; //数据库中所有可更新字段 + + final String deleteSQL; + + private final int logLevel; + + //---------------------计算主键值---------------------------- + private final int nodeid; + + final Class[] distributeTables; + + final boolean autoGenerated; + + final boolean distributed; + + boolean initedPrimaryValue = false; + + final AtomicLong primaryValue = new AtomicLong(0); + + final int allocationSize; + //------------------------------------------------------------ + public static EntityInfo load(Class clazz, final DataSource source) { EntityInfo rs = entityInfos.get(clazz); if (rs != null) return rs; synchronized (entityInfos) { rs = entityInfos.get(clazz); if (rs == null) { - final List cacheClasses = source instanceof DataJDBCSource ? ((DataJDBCSource) source).cacheClasses : null; - rs = new EntityInfo(clazz, cacheClasses); + rs = new EntityInfo(clazz, ((DataJDBCSource) source).nodeid, ((DataJDBCSource) source).cacheClasses); entityInfos.put(clazz, rs); if (rs.cache != null && source != null) { AutoLoad auto = clazz.getAnnotation(AutoLoad.class); @@ -66,45 +103,112 @@ public final class EntityInfo { } } - private EntityInfo(Class type, final List cacheClasses) { + private EntityInfo(Class type, int nodeid, final List cacheClasses) { this.type = type; + //--------------------------------------------- + this.nodeid = nodeid; + DistributeGenerator.DistributeTables dt = type.getAnnotation(DistributeGenerator.DistributeTables.class); + this.distributeTables = dt == null ? null : dt.value(); + + LogLevel ll = type.getAnnotation(LogLevel.class); + this.logLevel = ll == null ? Integer.MIN_VALUE : Level.parse(ll.value()).intValue(); + //--------------------------------------------- Table t = type.getAnnotation(Table.class); this.table = (t == null) ? type.getSimpleName().toLowerCase() : (t.catalog().isEmpty()) ? t.name() : (t.catalog() + '.' + t.name()); this.creator = Creator.create(type); - this.defaultTypeInstance = this.creator.create(); Attribute idAttr0 = null; - Class primaryType0 = null; - String primaryName = null; + Map aliasmap0 = null; Class cltmp = type; Set fields = new HashSet<>(); + List> queryattrs = new ArrayList<>(); + List insertcols = new ArrayList<>(); + List> insertattrs = new ArrayList<>(); + List updatecols = new ArrayList<>(); + List> updateattrs = new ArrayList<>(); + boolean auto = false; + boolean sqldistribute = false; + int allocationSize0 = 0; + do { for (Field field : cltmp.getDeclaredFields()) { if (Modifier.isStatic(field.getModifiers())) continue; if (Modifier.isFinal(field.getModifiers())) continue; if (field.getAnnotation(Transient.class) != null) continue; if (fields.contains(field.getName())) continue; + final String fieldname = field.getName(); final Column col = field.getAnnotation(Column.class); - final String sqlfield = col == null || col.name().isEmpty() ? field.getName() : col.name(); + final String sqlfield = col == null || col.name().isEmpty() ? fieldname : col.name(); + if (!fieldname.equals(sqlfield)) { + if (aliasmap0 == null) aliasmap0 = new HashMap<>(); + aliasmap0.put(fieldname, sqlfield); + } Attribute attr; try { - attr = Attribute.create(cltmp, sqlfield, field); + attr = Attribute.create(cltmp, field); } catch (RuntimeException e) { continue; } - if (field.getAnnotation(javax.persistence.Id.class) != null) { - if (idAttr0 == null) { - idAttr0 = attr; - primaryType0 = field.getType(); - primaryName = field.getName(); + if (field.getAnnotation(javax.persistence.Id.class) != null && idAttr0 == null) { + idAttr0 = attr; + GeneratedValue gv = field.getAnnotation(GeneratedValue.class); + auto = gv != null; + if (gv != null && gv.strategy() != GenerationType.IDENTITY) { + throw new RuntimeException(cltmp.getName() + "'s @ID primary not a GenerationType.IDENTITY"); + } + DistributeGenerator dg = field.getAnnotation(DistributeGenerator.class); + if (dg != null) { + if (!field.getType().isPrimitive()) throw new RuntimeException(cltmp.getName() + "'s @DistributeGenerator primary must be primitive class type field"); + sqldistribute = true; + auto = false; + allocationSize0 = dg.allocationSize(); + primaryValue.set(dg.initialValue()); + } + if (!auto) { + insertcols.add(sqlfield); + insertattrs.add(attr); + } + } else { + if (col == null || col.insertable()) { + insertcols.add(sqlfield); + insertattrs.add(attr); + } + if (col == null || col.updatable()) { + updatecols.add(sqlfield); + updateattrs.add(attr); } } - fields.add(field.getName()); - attributes.put(field.getName(), attr); + queryattrs.add(attr); + fields.add(fieldname); + attributes.put(fieldname, attr); } } while ((cltmp = cltmp.getSuperclass()) != Object.class); this.primary = idAttr0; - this.primaryType = primaryType0; - this.primaryFieldName = primaryName; + this.aliasmap = aliasmap0; + { + this.queryAttributes = queryattrs.toArray(new Attribute[queryattrs.size()]); + this.insertAttributes = insertattrs.toArray(new Attribute[insertattrs.size()]); + this.updateAttributes = updateattrs.toArray(new Attribute[updateattrs.size()]); + StringBuilder insertsb = new StringBuilder(); + StringBuilder insertsb2 = new StringBuilder(); + for (String col : insertcols) { + if (insertsb.length() > 0) insertsb.append(','); + insertsb.append(col); + if (insertsb2.length() > 0) insertsb2.append(','); + insertsb2.append('?'); + } + this.insertSQL = "INSERT INTO " + table + "(" + insertsb + ") VALUES(" + insertsb2 + ")"; + StringBuilder updatesb = new StringBuilder(); + for (String col : updatecols) { + if (updatesb.length() > 0) updatesb.append(','); + updatesb.append(col).append(" = ?"); + } + this.updateSQL = "UPDATE " + table + " SET " + updatesb + " WHERE " + getPrimarySQLColumn() + " = ?"; + this.deleteSQL = "DELETE FROM " + table + " WHERE " + getPrimarySQLColumn() + " = ?"; + this.querySQL = "SELECT * FROM " + table + " WHERE " + getPrimarySQLColumn() + " = ?"; + } + this.autoGenerated = auto; + this.distributed = sqldistribute; + this.allocationSize = allocationSize0; //----------------cache-------------- Cacheable c = type.getAnnotation(Cacheable.class); boolean cf = (c == null) ? (cacheClasses != null && cacheClasses.contains(type)) : false; @@ -115,6 +219,15 @@ public final class EntityInfo { } } + public void createPrimaryValue(T src) { + long v = allocationSize > 1 ? (primaryValue.incrementAndGet() * allocationSize + nodeid) : primaryValue.incrementAndGet(); + if (primary.type() == int.class || primary.type() == Integer.class) { + getPrimary().set(src, (Integer) ((Long) v).intValue()); + } else { + getPrimary().set(src, v); + } + } + EntityCache getCache() { return cache; } @@ -131,27 +244,53 @@ public final class EntityInfo { return table; } - public Class getPrimaryType() { - return this.primaryType; - } - - public Attribute getPrimary() { + public Attribute getPrimary() { return this.primary; } - public String getPrimaryField() { - return this.primaryFieldName; - } - public Attribute getAttribute(String fieldname) { return this.attributes.get(fieldname); } - public T getDefaultTypeInstance() { - return defaultTypeInstance; + public boolean isNoAlias() { + return this.aliasmap == null; + } + + //根据field字段名获取数据库对应的字段名 + public String getSQLColumn(String fieldname) { + return this.aliasmap == null ? fieldname : aliasmap.getOrDefault(fieldname, fieldname); + } + + //数据库字段名 + public String getPrimarySQLColumn() { + return getSQLColumn(this.primary.field()); } public Map> getAttributes() { return attributes; } + + public boolean isLoggable(Level l) { + return l.intValue() >= this.logLevel; + } + + public T getValue(SelectColumn sels, ResultSet set) throws SQLException { + T obj = creator.create(); + for (Attribute attr : queryAttributes) { + if (sels == null || sels.validate(attr.field())) { + Object o = 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) { + o = ((Number) o).shortValue(); + } + } + attr.set(obj, o); + } + } + return obj; + } } diff --git a/src/com/wentch/redkale/source/FilterNode.java b/src/com/wentch/redkale/source/FilterNode.java index b590cce5b..41586f66f 100644 --- a/src/com/wentch/redkale/source/FilterNode.java +++ b/src/com/wentch/redkale/source/FilterNode.java @@ -226,7 +226,7 @@ public class FilterNode { if (o instanceof CharSequence) { sb.append('"').append(o.toString().replace("\"", "\\\"")).append('"'); } else { - sb.append('"').append(o).append('"'); + sb.append(o); } } return sb.append(')').toString(); @@ -241,7 +241,7 @@ public class FilterNode { if (o instanceof CharSequence) { sb.append('"').append(o.toString().replace("\"", "\\\"")).append('"'); } else { - sb.append('"').append(o).append('"'); + sb.append(o); } } return sb.append(')').toString();