From 11d88c887f4850a4ede1c9a82e4ed40df8943331 Mon Sep 17 00:00:00 2001 From: redkale Date: Sat, 5 Aug 2023 08:11:11 +0800 Subject: [PATCH] =?UTF-8?q?EntityBuilder=E6=94=AF=E6=8C=81Map=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/redkale/source/DataSqlSource.java | 4 +- .../org/redkale/source/EntityBuilder.java | 160 +++++++++++------- .../java/org/redkale/source/EntityInfo.java | 2 +- 3 files changed, 104 insertions(+), 62 deletions(-) diff --git a/src/main/java/org/redkale/source/DataSqlSource.java b/src/main/java/org/redkale/source/DataSqlSource.java index bb45a3bcc..3c98ec050 100644 --- a/src/main/java/org/redkale/source/DataSqlSource.java +++ b/src/main/java/org/redkale/source/DataSqlSource.java @@ -35,7 +35,7 @@ public interface DataSqlSource extends DataSource { if (!rset.next()) { return null; } - if (type.isPrimitive() || type == byte[].class || type.getName().startsWith("java.")) { + if (type.isPrimitive() || type == byte[].class || (!Map.class.isAssignableFrom(type) && type.getName().startsWith("java."))) { return (V) formatColumnValue(type, rset.getObject(1)); } return EntityBuilder.load(type).getObjectValue(rset); @@ -44,7 +44,7 @@ public interface DataSqlSource extends DataSource { default List nativeQueryList(Class type, String sql) { return nativeQuery(sql, rset -> { - if (type.isPrimitive() || type == byte[].class || type.getName().startsWith("java.")) { + if (type.isPrimitive() || type == byte[].class || (!Map.class.isAssignableFrom(type) && type.getName().startsWith("java."))) { List list = new ArrayList<>(); while (rset.next()) { list.add(rset.wasNull() ? null : (V) formatColumnValue(type, rset.getObject(1))); diff --git a/src/main/java/org/redkale/source/EntityBuilder.java b/src/main/java/org/redkale/source/EntityBuilder.java index 9e1fd6707..6faec5d45 100644 --- a/src/main/java/org/redkale/source/EntityBuilder.java +++ b/src/main/java/org/redkale/source/EntityBuilder.java @@ -23,6 +23,12 @@ public class EntityBuilder { private static final ConcurrentHashMap cacheMap = new ConcurrentHashMap<>(); + //实体类名 + private final Class type; + + //是否Map类型的虚拟实体类 + private final boolean entityIsMap; + //Entity构建器 private final Creator creator; @@ -52,12 +58,13 @@ public class EntityBuilder { //数据库中所有字段, 顺序必须与querySqlColumns、querySqlColumnSequence一致 private final Attribute[] attributes; - EntityBuilder(Creator creator, + EntityBuilder(Class type, Creator creator, Map aliasmap, String[] constructorParameters, Attribute[] constructorAttributes, Attribute[] unconstructorAttributes, Map> attributeMap, Attribute[] queryAttributes) { + this.type = type; this.creator = creator; this.aliasmap = aliasmap; this.constructorParameters = constructorParameters; @@ -66,6 +73,7 @@ public class EntityBuilder { this.attributeMap = attributeMap; this.attributes = queryAttributes; this.sqlAttrMap = new HashMap<>(); + this.entityIsMap = Map.class.isAssignableFrom(type); attributeMap.forEach((k, v) -> sqlAttrMap.put(getSQLColumn(null, k), v)); } @@ -76,66 +84,70 @@ public class EntityBuilder { private static EntityBuilder create(Class type) { Creator creator = Creator.create(type); String[] constructorParameters = null; - try { - Method cm = creator.getClass().getMethod("create", Object[].class); - RedkaleClassLoader.putReflectionPublicMethods(creator.getClass().getName()); - RedkaleClassLoader.putReflectionMethod(creator.getClass().getName(), cm); - org.redkale.annotation.ConstructorParameters cp = cm.getAnnotation(org.redkale.annotation.ConstructorParameters.class); - if (cp != null && cp.value().length > 0) { - constructorParameters = cp.value(); - } else { - org.redkale.util.ConstructorParameters cp2 = cm.getAnnotation(org.redkale.util.ConstructorParameters.class); - if (cp2 != null && cp2.value().length > 0) { - constructorParameters = cp2.value(); + if (!Map.class.isAssignableFrom(type)) { + try { + Method cm = creator.getClass().getMethod("create", Object[].class); + RedkaleClassLoader.putReflectionPublicMethods(creator.getClass().getName()); + RedkaleClassLoader.putReflectionMethod(creator.getClass().getName(), cm); + org.redkale.annotation.ConstructorParameters cp = cm.getAnnotation(org.redkale.annotation.ConstructorParameters.class); + if (cp != null && cp.value().length > 0) { + constructorParameters = cp.value(); + } else { + org.redkale.util.ConstructorParameters cp2 = cm.getAnnotation(org.redkale.util.ConstructorParameters.class); + if (cp2 != null && cp2.value().length > 0) { + constructorParameters = cp2.value(); + } } + } catch (Exception e) { + throw new SourceException(type + " cannot find ConstructorParameters Creator"); } - } catch (Exception e) { - throw new SourceException(type + " cannot find ConstructorParameters Creator"); } Class cltmp = type; Map aliasmap = null; Set fields = new HashSet<>(); List> queryAttrs = new ArrayList<>(); HashMap> attributeMap = new HashMap<>(); - do { - RedkaleClassLoader.putReflectionDeclaredFields(cltmp.getName()); - 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 (field.getAnnotation(javax.persistence.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() ? fieldName : col.name(); - if (!fieldName.equals(sqlField)) { - if (aliasmap == null) { - aliasmap = new HashMap<>(); + if (!Map.class.isAssignableFrom(type)) { + do { + RedkaleClassLoader.putReflectionDeclaredFields(cltmp.getName()); + for (Field field : cltmp.getDeclaredFields()) { + if (Modifier.isStatic(field.getModifiers())) { + continue; } - aliasmap.put(fieldName, sqlField); + if (Modifier.isFinal(field.getModifiers())) { + continue; + } + if (field.getAnnotation(Transient.class) != null) { + continue; + } + if (field.getAnnotation(javax.persistence.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() ? fieldName : col.name(); + if (!fieldName.equals(sqlField)) { + if (aliasmap == null) { + aliasmap = new HashMap<>(); + } + aliasmap.put(fieldName, sqlField); + } + Attribute attr; + try { + attr = Attribute.create(type, cltmp, field); + } catch (RuntimeException e) { + continue; + } + RedkaleClassLoader.putReflectionField(cltmp.getName(), field); + queryAttrs.add(attr); + fields.add(fieldName); + attributeMap.put(fieldName, attr); } - Attribute attr; - try { - attr = Attribute.create(type, cltmp, field); - } catch (RuntimeException e) { - continue; - } - RedkaleClassLoader.putReflectionField(cltmp.getName(), field); - queryAttrs.add(attr); - fields.add(fieldName); - attributeMap.put(fieldName, attr); - } - } while ((cltmp = cltmp.getSuperclass()) != Object.class); + } while ((cltmp = cltmp.getSuperclass()) != Object.class); + } Attribute[] constructorAttributes; Attribute[] unconstructorAttributes; if (constructorParameters == null) { @@ -144,8 +156,8 @@ public class EntityBuilder { } else { constructorAttributes = new Attribute[constructorParameters.length]; List> unconstructorAttrs = new ArrayList<>(); - List newquerycols1 = new ArrayList<>(); - List newquerycols2 = new ArrayList<>(); + List newQueryCols1 = new ArrayList<>(); + List newQueryCols2 = new ArrayList<>(); for (Attribute attr : new ArrayList<>(queryAttrs)) { int pos = -1; for (int i = 0; i < constructorParameters.length; i++) { @@ -161,13 +173,13 @@ public class EntityBuilder { } } unconstructorAttributes = unconstructorAttrs.toArray(new Attribute[unconstructorAttrs.size()]); - newquerycols1.addAll(newquerycols2); - List> newqueryattrs = new ArrayList<>(); - newqueryattrs.addAll(List.of(constructorAttributes)); - newqueryattrs.addAll(unconstructorAttrs); - queryAttrs = newqueryattrs; + newQueryCols1.addAll(newQueryCols2); + List> newQueryAttrs = new ArrayList<>(); + newQueryAttrs.addAll(List.of(constructorAttributes)); + newQueryAttrs.addAll(unconstructorAttrs); + queryAttrs = newQueryAttrs; } - return new EntityBuilder<>(creator, aliasmap, constructorParameters, constructorAttributes, + return new EntityBuilder<>(type, creator, aliasmap, constructorParameters, constructorAttributes, unconstructorAttributes, attributeMap, queryAttrs.toArray(new Attribute[queryAttrs.size()])); } @@ -192,6 +204,14 @@ public class EntityBuilder { if (sqlColumns == null) { sqlColumns = row.getColumnLabels(); } + if (entityIsMap) { + final Map map = (Map) creator.create(); + obj = (T) map; + for (String sqlCol : sqlColumns) { + map.put(sqlCol, getFieldValue(row, sqlCol)); + } + return obj; + } Map> attrs = this.sqlAttrMap; if (this.constructorParameters == null) { obj = creator.create(); @@ -241,6 +261,13 @@ public class EntityBuilder { if (row.wasNull()) { return null; } + if (entityIsMap) { + final Map map = (Map) creator.create(); + for (String sqlCol : row.getColumnLabels()) { + map.put(sqlCol, getFieldValue(row, sqlCol)); + } + return (T) map; + } T obj; Attribute[] attrs = this.attributes; if (this.constructorParameters == null) { @@ -293,6 +320,13 @@ public class EntityBuilder { if (row.wasNull()) { return null; } + if (entityIsMap) { + final Map map = (Map) creator.create(); + for (String sqlCol : row.getColumnLabels()) { + map.put(sqlCol, getFieldValue(row, sqlCol)); + } + return (T) map; + } T obj; int index = 0; if (this.constructorParameters == null) { @@ -358,6 +392,10 @@ public class EntityBuilder { return obj; } + protected Serializable getFieldValue(final DataResultSetRow row, String sqlColumn) { + return (Serializable) row.getObject(sqlColumn); + } + protected Serializable getFieldValue(Attribute attr, final DataResultSetRow row, int index) { return row.getObject(attr, index, index > 0 ? null : this.getSQLColumn(null, attr.field())); } @@ -394,4 +432,8 @@ public class EntityBuilder { return creator; } + @ConvertDisabled + public Class getType() { + return type; + } } diff --git a/src/main/java/org/redkale/source/EntityInfo.java b/src/main/java/org/redkale/source/EntityInfo.java index 6696aa823..4a766c0dd 100644 --- a/src/main/java/org/redkale/source/EntityInfo.java +++ b/src/main/java/org/redkale/source/EntityInfo.java @@ -565,7 +565,7 @@ public final class EntityInfo { String field = this.queryAttributes[i].field(); this.queryColumns[i] = Utility.find(this.ddlColumns, c -> c.field.equals(field)); } - this.builder = new EntityBuilder<>(creator, aliasmap, constructorParameters, constructorAttributes, unconstructorAttributes, attributeMap, queryAttributes); + this.builder = new EntityBuilder<>(type, creator, aliasmap, constructorParameters, constructorAttributes, unconstructorAttributes, attributeMap, queryAttributes); if (table != null) { StringBuilder querydb = new StringBuilder();