EntityBuilder支持Map类型

This commit is contained in:
redkale
2023-08-05 08:11:11 +08:00
parent 213a9a362d
commit 11d88c887f
3 changed files with 104 additions and 62 deletions

View File

@@ -35,7 +35,7 @@ public interface DataSqlSource extends DataSource {
if (!rset.next()) { if (!rset.next()) {
return null; 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 (V) formatColumnValue(type, rset.getObject(1));
} }
return EntityBuilder.load(type).getObjectValue(rset); return EntityBuilder.load(type).getObjectValue(rset);
@@ -44,7 +44,7 @@ public interface DataSqlSource extends DataSource {
default <V> List<V> nativeQueryList(Class<V> type, String sql) { default <V> List<V> nativeQueryList(Class<V> type, String sql) {
return nativeQuery(sql, rset -> { 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<V> list = new ArrayList<>(); List<V> list = new ArrayList<>();
while (rset.next()) { while (rset.next()) {
list.add(rset.wasNull() ? null : (V) formatColumnValue(type, rset.getObject(1))); list.add(rset.wasNull() ? null : (V) formatColumnValue(type, rset.getObject(1)));

View File

@@ -23,6 +23,12 @@ public class EntityBuilder<T> {
private static final ConcurrentHashMap<Class, EntityBuilder> cacheMap = new ConcurrentHashMap<>(); private static final ConcurrentHashMap<Class, EntityBuilder> cacheMap = new ConcurrentHashMap<>();
//实体类名
private final Class<T> type;
//是否Map类型的虚拟实体类
private final boolean entityIsMap;
//Entity构建器 //Entity构建器
private final Creator<T> creator; private final Creator<T> creator;
@@ -52,12 +58,13 @@ public class EntityBuilder<T> {
//数据库中所有字段, 顺序必须与querySqlColumns、querySqlColumnSequence一致 //数据库中所有字段, 顺序必须与querySqlColumns、querySqlColumnSequence一致
private final Attribute<T, Serializable>[] attributes; private final Attribute<T, Serializable>[] attributes;
EntityBuilder(Creator<T> creator, EntityBuilder(Class<T> type, Creator<T> creator,
Map<String, String> aliasmap, String[] constructorParameters, Map<String, String> aliasmap, String[] constructorParameters,
Attribute<T, Serializable>[] constructorAttributes, Attribute<T, Serializable>[] constructorAttributes,
Attribute<T, Serializable>[] unconstructorAttributes, Attribute<T, Serializable>[] unconstructorAttributes,
Map<String, Attribute<T, Serializable>> attributeMap, Map<String, Attribute<T, Serializable>> attributeMap,
Attribute<T, Serializable>[] queryAttributes) { Attribute<T, Serializable>[] queryAttributes) {
this.type = type;
this.creator = creator; this.creator = creator;
this.aliasmap = aliasmap; this.aliasmap = aliasmap;
this.constructorParameters = constructorParameters; this.constructorParameters = constructorParameters;
@@ -66,6 +73,7 @@ public class EntityBuilder<T> {
this.attributeMap = attributeMap; this.attributeMap = attributeMap;
this.attributes = queryAttributes; this.attributes = queryAttributes;
this.sqlAttrMap = new HashMap<>(); this.sqlAttrMap = new HashMap<>();
this.entityIsMap = Map.class.isAssignableFrom(type);
attributeMap.forEach((k, v) -> sqlAttrMap.put(getSQLColumn(null, k), v)); attributeMap.forEach((k, v) -> sqlAttrMap.put(getSQLColumn(null, k), v));
} }
@@ -76,6 +84,7 @@ public class EntityBuilder<T> {
private static <T> EntityBuilder<T> create(Class<T> type) { private static <T> EntityBuilder<T> create(Class<T> type) {
Creator<T> creator = Creator.create(type); Creator<T> creator = Creator.create(type);
String[] constructorParameters = null; String[] constructorParameters = null;
if (!Map.class.isAssignableFrom(type)) {
try { try {
Method cm = creator.getClass().getMethod("create", Object[].class); Method cm = creator.getClass().getMethod("create", Object[].class);
RedkaleClassLoader.putReflectionPublicMethods(creator.getClass().getName()); RedkaleClassLoader.putReflectionPublicMethods(creator.getClass().getName());
@@ -92,11 +101,13 @@ public class EntityBuilder<T> {
} catch (Exception e) { } catch (Exception e) {
throw new SourceException(type + " cannot find ConstructorParameters Creator"); throw new SourceException(type + " cannot find ConstructorParameters Creator");
} }
}
Class cltmp = type; Class cltmp = type;
Map<String, String> aliasmap = null; Map<String, String> aliasmap = null;
Set<String> fields = new HashSet<>(); Set<String> fields = new HashSet<>();
List<Attribute<T, Serializable>> queryAttrs = new ArrayList<>(); List<Attribute<T, Serializable>> queryAttrs = new ArrayList<>();
HashMap<String, Attribute<T, Serializable>> attributeMap = new HashMap<>(); HashMap<String, Attribute<T, Serializable>> attributeMap = new HashMap<>();
if (!Map.class.isAssignableFrom(type)) {
do { do {
RedkaleClassLoader.putReflectionDeclaredFields(cltmp.getName()); RedkaleClassLoader.putReflectionDeclaredFields(cltmp.getName());
for (Field field : cltmp.getDeclaredFields()) { for (Field field : cltmp.getDeclaredFields()) {
@@ -136,6 +147,7 @@ public class EntityBuilder<T> {
attributeMap.put(fieldName, attr); attributeMap.put(fieldName, attr);
} }
} while ((cltmp = cltmp.getSuperclass()) != Object.class); } while ((cltmp = cltmp.getSuperclass()) != Object.class);
}
Attribute<T, Serializable>[] constructorAttributes; Attribute<T, Serializable>[] constructorAttributes;
Attribute<T, Serializable>[] unconstructorAttributes; Attribute<T, Serializable>[] unconstructorAttributes;
if (constructorParameters == null) { if (constructorParameters == null) {
@@ -144,8 +156,8 @@ public class EntityBuilder<T> {
} else { } else {
constructorAttributes = new Attribute[constructorParameters.length]; constructorAttributes = new Attribute[constructorParameters.length];
List<Attribute<T, Serializable>> unconstructorAttrs = new ArrayList<>(); List<Attribute<T, Serializable>> unconstructorAttrs = new ArrayList<>();
List<String> newquerycols1 = new ArrayList<>(); List<String> newQueryCols1 = new ArrayList<>();
List<String> newquerycols2 = new ArrayList<>(); List<String> newQueryCols2 = new ArrayList<>();
for (Attribute<T, Serializable> attr : new ArrayList<>(queryAttrs)) { for (Attribute<T, Serializable> attr : new ArrayList<>(queryAttrs)) {
int pos = -1; int pos = -1;
for (int i = 0; i < constructorParameters.length; i++) { for (int i = 0; i < constructorParameters.length; i++) {
@@ -161,13 +173,13 @@ public class EntityBuilder<T> {
} }
} }
unconstructorAttributes = unconstructorAttrs.toArray(new Attribute[unconstructorAttrs.size()]); unconstructorAttributes = unconstructorAttrs.toArray(new Attribute[unconstructorAttrs.size()]);
newquerycols1.addAll(newquerycols2); newQueryCols1.addAll(newQueryCols2);
List<Attribute<T, Serializable>> newqueryattrs = new ArrayList<>(); List<Attribute<T, Serializable>> newQueryAttrs = new ArrayList<>();
newqueryattrs.addAll(List.of(constructorAttributes)); newQueryAttrs.addAll(List.of(constructorAttributes));
newqueryattrs.addAll(unconstructorAttrs); newQueryAttrs.addAll(unconstructorAttrs);
queryAttrs = newqueryattrs; 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()])); unconstructorAttributes, attributeMap, queryAttrs.toArray(new Attribute[queryAttrs.size()]));
} }
@@ -192,6 +204,14 @@ public class EntityBuilder<T> {
if (sqlColumns == null) { if (sqlColumns == null) {
sqlColumns = row.getColumnLabels(); 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<String, Attribute<T, Serializable>> attrs = this.sqlAttrMap; Map<String, Attribute<T, Serializable>> attrs = this.sqlAttrMap;
if (this.constructorParameters == null) { if (this.constructorParameters == null) {
obj = creator.create(); obj = creator.create();
@@ -241,6 +261,13 @@ public class EntityBuilder<T> {
if (row.wasNull()) { if (row.wasNull()) {
return null; 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; T obj;
Attribute<T, Serializable>[] attrs = this.attributes; Attribute<T, Serializable>[] attrs = this.attributes;
if (this.constructorParameters == null) { if (this.constructorParameters == null) {
@@ -293,6 +320,13 @@ public class EntityBuilder<T> {
if (row.wasNull()) { if (row.wasNull()) {
return null; 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; T obj;
int index = 0; int index = 0;
if (this.constructorParameters == null) { if (this.constructorParameters == null) {
@@ -358,6 +392,10 @@ public class EntityBuilder<T> {
return obj; return obj;
} }
protected Serializable getFieldValue(final DataResultSetRow row, String sqlColumn) {
return (Serializable) row.getObject(sqlColumn);
}
protected Serializable getFieldValue(Attribute<T, Serializable> attr, final DataResultSetRow row, int index) { protected Serializable getFieldValue(Attribute<T, Serializable> attr, final DataResultSetRow row, int index) {
return row.getObject(attr, index, index > 0 ? null : this.getSQLColumn(null, attr.field())); return row.getObject(attr, index, index > 0 ? null : this.getSQLColumn(null, attr.field()));
} }
@@ -394,4 +432,8 @@ public class EntityBuilder<T> {
return creator; return creator;
} }
@ConvertDisabled
public Class<T> getType() {
return type;
}
} }

View File

@@ -565,7 +565,7 @@ public final class EntityInfo<T> {
String field = this.queryAttributes[i].field(); String field = this.queryAttributes[i].field();
this.queryColumns[i] = Utility.find(this.ddlColumns, c -> c.field.equals(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) { if (table != null) {
StringBuilder querydb = new StringBuilder(); StringBuilder querydb = new StringBuilder();