增加EntityBuilder功能
This commit is contained in:
@@ -338,35 +338,6 @@ public abstract class AbstractDataSource extends AbstractService implements Data
|
|||||||
return node.createPredicate(cache);
|
return node.createPredicate(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据ResultSet获取对象
|
|
||||||
*
|
|
||||||
* @param <T> 泛型
|
|
||||||
* @param info EntityInfo
|
|
||||||
* @param sels 过滤字段
|
|
||||||
* @param row ResultSet
|
|
||||||
*
|
|
||||||
* @return 对象
|
|
||||||
*/
|
|
||||||
protected <T> T getEntityValue(EntityInfo<T> info, final SelectColumn sels, final EntityInfo.DataResultSetRow row) {
|
|
||||||
return sels == null ? info.getFullEntityValue(row) : info.getEntityValue(sels, row);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据ResultSet获取对象
|
|
||||||
*
|
|
||||||
* @param <T> 泛型
|
|
||||||
* @param info EntityInfo
|
|
||||||
* @param constructorAttrs 构造函数字段
|
|
||||||
* @param unconstructorAttrs 非构造函数字段
|
|
||||||
* @param row ResultSet
|
|
||||||
*
|
|
||||||
* @return 对象
|
|
||||||
*/
|
|
||||||
protected <T> T getEntityValue(EntityInfo<T> info, final Attribute<T, Serializable>[] constructorAttrs, final Attribute<T, Serializable>[] unconstructorAttrs, final EntityInfo.DataResultSetRow row) {
|
|
||||||
return info.getEntityValue(constructorAttrs, unconstructorAttrs, row);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据翻页参数构建排序SQL
|
* 根据翻页参数构建排序SQL
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -330,7 +330,7 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource implement
|
|||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("CREATE TABLE IF NOT EXISTS `").append(info.getOriginTable()).append("`(\n");
|
sb.append("CREATE TABLE IF NOT EXISTS `").append(info.getOriginTable()).append("`(\n");
|
||||||
EntityColumn primary = null;
|
EntityColumn primary = null;
|
||||||
T one = info.constructorAttributes == null ? info.getCreator().create() : null;
|
T one = !info.getBuilder().hasConstructorAttribute() ? info.getCreator().create() : null;
|
||||||
for (EntityColumn column : info.getDDLColumns()) {
|
for (EntityColumn column : info.getDDLColumns()) {
|
||||||
if (column.primary) {
|
if (column.primary) {
|
||||||
primary = column;
|
primary = column;
|
||||||
@@ -458,7 +458,7 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource implement
|
|||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("CREATE TABLE IF NOT EXISTS ").append(info.getOriginTable()).append("(\n");
|
sb.append("CREATE TABLE IF NOT EXISTS ").append(info.getOriginTable()).append("(\n");
|
||||||
EntityColumn primary = null;
|
EntityColumn primary = null;
|
||||||
T one = info.constructorAttributes == null ? info.getCreator().create() : null;
|
T one = !info.getBuilder().hasConstructorAttribute() ? info.getCreator().create() : null;
|
||||||
List<String> comments = new ArrayList<>();
|
List<String> comments = new ArrayList<>();
|
||||||
if (table != null && !table.comment().isEmpty()) {
|
if (table != null && !table.comment().isEmpty()) {
|
||||||
comments.add("COMMENT ON TABLE " + info.getOriginTable() + " IS '" + table.comment().replace('\'', '"') + "'");
|
comments.add("COMMENT ON TABLE " + info.getOriginTable() + " IS '" + table.comment().replace('\'', '"') + "'");
|
||||||
|
|||||||
@@ -1806,7 +1806,7 @@ public class DataJdbcSource extends AbstractDataSqlSource {
|
|||||||
prestmt = conn.prepareQueryStatement(prepareSQL);
|
prestmt = conn.prepareQueryStatement(prepareSQL);
|
||||||
prestmt.setObject(1, pk);
|
prestmt.setObject(1, pk);
|
||||||
final DataResultSet set = createDataResultSet(info, prestmt.executeQuery());
|
final DataResultSet set = createDataResultSet(info, prestmt.executeQuery());
|
||||||
T rs = set.next() ? info.getFullEntityValue(set) : null;
|
T rs = set.next() ? info.getBuilder().getFullEntityValue(set) : null;
|
||||||
set.close();
|
set.close();
|
||||||
conn.offerQueryStatement(prestmt);
|
conn.offerQueryStatement(prestmt);
|
||||||
slowLog(s, prepareSQL);
|
slowLog(s, prepareSQL);
|
||||||
@@ -1838,7 +1838,7 @@ public class DataJdbcSource extends AbstractDataSqlSource {
|
|||||||
prestmt = conn.prepareQueryStatement(sql);
|
prestmt = conn.prepareQueryStatement(sql);
|
||||||
prestmt.setFetchSize(1);
|
prestmt.setFetchSize(1);
|
||||||
final DataResultSet set = createDataResultSet(info, prestmt.executeQuery());
|
final DataResultSet set = createDataResultSet(info, prestmt.executeQuery());
|
||||||
T rs = set.next() ? selects == null ? info.getFullEntityValue(set) : info.getEntityValue(selects, set) : null;
|
T rs = set.next() ? selects == null ? info.getBuilder().getFullEntityValue(set) : info.getBuilder().getEntityValue(selects, set) : null;
|
||||||
set.close();
|
set.close();
|
||||||
conn.offerQueryStatement(prestmt);
|
conn.offerQueryStatement(prestmt);
|
||||||
slowLog(s, sql);
|
slowLog(s, sql);
|
||||||
@@ -1884,7 +1884,7 @@ public class DataJdbcSource extends AbstractDataSqlSource {
|
|||||||
prestmt = conn.prepareQueryStatement(sql);
|
prestmt = conn.prepareQueryStatement(sql);
|
||||||
prestmt.setFetchSize(1);
|
prestmt.setFetchSize(1);
|
||||||
final DataResultSet set = createDataResultSet(info, prestmt.executeQuery());
|
final DataResultSet set = createDataResultSet(info, prestmt.executeQuery());
|
||||||
T rs = set.next() ? selects == null ? info.getFullEntityValue(set) : info.getEntityValue(selects, set) : null;
|
T rs = set.next() ? selects == null ? info.getBuilder().getFullEntityValue(set) : info.getBuilder().getEntityValue(selects, set) : null;
|
||||||
set.close();
|
set.close();
|
||||||
conn.offerQueryStatement(prestmt);
|
conn.offerQueryStatement(prestmt);
|
||||||
slowLog(s, sql);
|
slowLog(s, sql);
|
||||||
@@ -1920,7 +1920,7 @@ public class DataJdbcSource extends AbstractDataSqlSource {
|
|||||||
final DataResultSet set = createDataResultSet(info, prestmt.executeQuery());
|
final DataResultSet set = createDataResultSet(info, prestmt.executeQuery());
|
||||||
Serializable val = defValue;
|
Serializable val = defValue;
|
||||||
if (set.next()) {
|
if (set.next()) {
|
||||||
val = info.getFieldValue(attr, set, 1);
|
val = info.getBuilder().getFieldValue(attr, set, 1);
|
||||||
}
|
}
|
||||||
set.close();
|
set.close();
|
||||||
conn.offerQueryStatement(prestmt);
|
conn.offerQueryStatement(prestmt);
|
||||||
@@ -1969,7 +1969,7 @@ public class DataJdbcSource extends AbstractDataSqlSource {
|
|||||||
final DataResultSet set = createDataResultSet(info, prestmt.executeQuery());
|
final DataResultSet set = createDataResultSet(info, prestmt.executeQuery());
|
||||||
Serializable val = defValue;
|
Serializable val = defValue;
|
||||||
if (set.next()) {
|
if (set.next()) {
|
||||||
val = info.getFieldValue(attr, set, 1);
|
val = info.getBuilder().getFieldValue(attr, set, 1);
|
||||||
}
|
}
|
||||||
set.close();
|
set.close();
|
||||||
conn.offerQueryStatement(prestmt);
|
conn.offerQueryStatement(prestmt);
|
||||||
@@ -2275,10 +2275,11 @@ public class DataJdbcSource extends AbstractDataSqlSource {
|
|||||||
final int limit = flipper == null || flipper.getLimit() < 1 ? Integer.MAX_VALUE : flipper.getLimit();
|
final int limit = flipper == null || flipper.getLimit() < 1 ? Integer.MAX_VALUE : flipper.getLimit();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
final DataResultSet rr = createDataResultSet(info, set);
|
final DataResultSet rr = createDataResultSet(info, set);
|
||||||
|
EntityBuilder<T> builder = info.getBuilder();
|
||||||
if (sels == null) {
|
if (sels == null) {
|
||||||
while (set.next()) {
|
while (set.next()) {
|
||||||
i++;
|
i++;
|
||||||
list.add(info.getFullEntityValue(rr));
|
list.add(builder.getFullEntityValue(rr));
|
||||||
if (limit <= i) {
|
if (limit <= i) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2286,7 +2287,7 @@ public class DataJdbcSource extends AbstractDataSqlSource {
|
|||||||
} else {
|
} else {
|
||||||
while (set.next()) {
|
while (set.next()) {
|
||||||
i++;
|
i++;
|
||||||
list.add(info.getEntityValue(sels, rr));
|
list.add(builder.getEntityValue(sels, rr));
|
||||||
if (limit <= i) {
|
if (limit <= i) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
312
src/main/java/org/redkale/source/EntityBuilder.java
Normal file
312
src/main/java/org/redkale/source/EntityBuilder.java
Normal file
@@ -0,0 +1,312 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.redkale.source;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.lang.reflect.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import org.redkale.annotation.Nullable;
|
||||||
|
import org.redkale.persistence.*;
|
||||||
|
import org.redkale.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可以是实体类,也可以是查询结果的JavaBean类
|
||||||
|
*
|
||||||
|
* @author zhangjx
|
||||||
|
* @since 2.8.0
|
||||||
|
*/
|
||||||
|
public class EntityBuilder<T> {
|
||||||
|
|
||||||
|
private static final ConcurrentHashMap<Class, EntityBuilder> cacheMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
//Entity构建器
|
||||||
|
private final Creator<T> creator;
|
||||||
|
|
||||||
|
//Entity构建器参数
|
||||||
|
@Nullable
|
||||||
|
private final String[] constructorParameters;
|
||||||
|
|
||||||
|
//key是field的name, value是Column的别名,即数据库表的字段名
|
||||||
|
//只有field.name 与 Column.name不同才存放在aliasmap里.
|
||||||
|
@Nullable
|
||||||
|
private final Map<String, String> aliasmap;
|
||||||
|
|
||||||
|
//Entity构建器参数Attribute, 数组个数与constructorParameters相同
|
||||||
|
@Nullable
|
||||||
|
private final Attribute<T, Serializable>[] constructorAttributes;
|
||||||
|
|
||||||
|
//Entity构建器参数Attribute
|
||||||
|
@Nullable
|
||||||
|
private final Attribute<T, Serializable>[] unconstructorAttributes;
|
||||||
|
|
||||||
|
private final HashMap<String, Attribute<T, Serializable>> attributeMap;
|
||||||
|
|
||||||
|
//数据库中所有字段, 顺序必须与querySqlColumns、querySqlColumnSequence一致
|
||||||
|
private final Attribute<T, Serializable>[] attributes;
|
||||||
|
|
||||||
|
EntityBuilder(Creator<T> creator,
|
||||||
|
Map<String, String> aliasmap, String[] constructorParameters,
|
||||||
|
Attribute<T, Serializable>[] constructorAttributes,
|
||||||
|
Attribute<T, Serializable>[] unconstructorAttributes,
|
||||||
|
HashMap<String, Attribute<T, Serializable>> attributeMap,
|
||||||
|
Attribute<T, Serializable>[] queryAttributes) {
|
||||||
|
this.creator = creator;
|
||||||
|
this.aliasmap = aliasmap;
|
||||||
|
this.constructorParameters = constructorParameters;
|
||||||
|
this.constructorAttributes = constructorAttributes;
|
||||||
|
this.unconstructorAttributes = unconstructorAttributes;
|
||||||
|
this.attributeMap = attributeMap;
|
||||||
|
this.attributes = queryAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> EntityBuilder<T> load(Class<T> type) {
|
||||||
|
return cacheMap.computeIfAbsent(type, t -> create(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> EntityBuilder<T> create(Class<T> type) {
|
||||||
|
Creator<T> 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new SourceException(type + " cannot find ConstructorParameters Creator");
|
||||||
|
}
|
||||||
|
Class cltmp = type;
|
||||||
|
Map<String, String> aliasmap = null;
|
||||||
|
Set<String> fields = new HashSet<>();
|
||||||
|
List<Attribute<T, Serializable>> queryAttrs = new ArrayList<>();
|
||||||
|
HashMap<String, Attribute<T, Serializable>> 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<>();
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
} while ((cltmp = cltmp.getSuperclass()) != Object.class);
|
||||||
|
Attribute<T, Serializable>[] constructorAttributes;
|
||||||
|
Attribute<T, Serializable>[] unconstructorAttributes;
|
||||||
|
if (constructorParameters == null) {
|
||||||
|
constructorAttributes = null;
|
||||||
|
unconstructorAttributes = null;
|
||||||
|
} else {
|
||||||
|
constructorAttributes = new Attribute[constructorParameters.length];
|
||||||
|
List<Attribute<T, Serializable>> unconstructorAttrs = new ArrayList<>();
|
||||||
|
List<String> newquerycols1 = new ArrayList<>();
|
||||||
|
List<String> newquerycols2 = new ArrayList<>();
|
||||||
|
for (Attribute<T, Serializable> attr : new ArrayList<>(queryAttrs)) {
|
||||||
|
int pos = -1;
|
||||||
|
for (int i = 0; i < constructorParameters.length; i++) {
|
||||||
|
if (attr.field().equals(constructorParameters[i])) {
|
||||||
|
pos = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pos >= 0) {
|
||||||
|
constructorAttributes[pos] = attr;
|
||||||
|
} else {
|
||||||
|
unconstructorAttrs.add(attr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unconstructorAttributes = unconstructorAttrs.toArray(new Attribute[unconstructorAttrs.size()]);
|
||||||
|
newquerycols1.addAll(newquerycols2);
|
||||||
|
List<Attribute<T, Serializable>> newqueryattrs = new ArrayList<>();
|
||||||
|
newqueryattrs.addAll(List.of(constructorAttributes));
|
||||||
|
newqueryattrs.addAll(unconstructorAttrs);
|
||||||
|
queryAttrs = newqueryattrs;
|
||||||
|
}
|
||||||
|
return new EntityBuilder<>(creator, aliasmap, constructorParameters, constructorAttributes,
|
||||||
|
unconstructorAttributes, attributeMap, queryAttrs.toArray(new Attribute[queryAttrs.size()]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将一行的ResultSet组装成一个Entity对象
|
||||||
|
*
|
||||||
|
* @param sels 指定字段
|
||||||
|
* @param row ResultSet
|
||||||
|
*
|
||||||
|
* @return Entity对象
|
||||||
|
*/
|
||||||
|
public T getEntityValue(final SelectColumn sels, final EntityInfo.DataResultSetRow row) {
|
||||||
|
if (row.wasNull()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
T obj;
|
||||||
|
Attribute<T, Serializable>[] attrs = this.attributes;
|
||||||
|
if (this.constructorParameters == null) {
|
||||||
|
obj = creator.create();
|
||||||
|
} else {
|
||||||
|
Object[] cps = new Object[this.constructorParameters.length];
|
||||||
|
for (int i = 0; i < this.constructorAttributes.length; i++) {
|
||||||
|
Attribute<T, Serializable> attr = this.constructorAttributes[i];
|
||||||
|
if (sels == null || sels.test(attr.field())) {
|
||||||
|
cps[i] = getFieldValue(attr, row, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
obj = creator.create(cps);
|
||||||
|
attrs = this.unconstructorAttributes;
|
||||||
|
}
|
||||||
|
for (Attribute<T, Serializable> attr : attrs) {
|
||||||
|
if (sels == null || sels.test(attr.field())) {
|
||||||
|
attr.set(obj, getFieldValue(attr, row, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getFullEntityValue(final EntityInfo.DataResultSetRow row) {
|
||||||
|
return getEntityValue(constructorAttributes, constructorAttributes == null ? attributes : unconstructorAttributes, row);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getFullEntityValue(final Serializable... values) {
|
||||||
|
return getEntityValue(constructorAttributes, constructorAttributes == null ? attributes : unconstructorAttributes, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将一行的ResultSet组装成一个Entity对象
|
||||||
|
*
|
||||||
|
* @param constructorAttrs 构建函数的Attribute数组, 大小必须与this.constructorAttributes相同
|
||||||
|
* @param unconstructorAttrs 非构建函数的Attribute数组
|
||||||
|
* @param row ResultSet
|
||||||
|
*
|
||||||
|
* @return Entity对象
|
||||||
|
*/
|
||||||
|
public T getEntityValue(final Attribute<T, Serializable>[] constructorAttrs, final Attribute<T, Serializable>[] unconstructorAttrs, final EntityInfo.DataResultSetRow row) {
|
||||||
|
if (row.wasNull()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
T obj;
|
||||||
|
int index = 0;
|
||||||
|
if (this.constructorParameters == null) {
|
||||||
|
obj = creator.create();
|
||||||
|
} else {
|
||||||
|
Object[] cps = new Object[this.constructorParameters.length];
|
||||||
|
for (int i = 0; i < constructorAttrs.length; i++) {
|
||||||
|
Attribute<T, Serializable> attr = constructorAttrs[i];
|
||||||
|
if (attr == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cps[i] = getFieldValue(attr, row, ++index);
|
||||||
|
}
|
||||||
|
obj = creator.create(cps);
|
||||||
|
}
|
||||||
|
if (unconstructorAttrs != null) {
|
||||||
|
for (Attribute<T, Serializable> attr : unconstructorAttrs) {
|
||||||
|
if (attr == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
attr.set(obj, getFieldValue(attr, row, ++index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将一行的ResultSet组装成一个Entity对象
|
||||||
|
*
|
||||||
|
* @param constructorAttrs 构建函数的Attribute数组, 大小必须与this.constructorAttributes相同
|
||||||
|
* @param unconstructorAttrs 非构建函数的Attribute数组
|
||||||
|
* @param values 字段值集合
|
||||||
|
*
|
||||||
|
* @return Entity对象
|
||||||
|
*/
|
||||||
|
public T getEntityValue(final Attribute<T, Serializable>[] constructorAttrs, final Attribute<T, Serializable>[] unconstructorAttrs, final Serializable... values) {
|
||||||
|
if (values == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
T obj;
|
||||||
|
int index = -1;
|
||||||
|
if (this.constructorParameters == null) {
|
||||||
|
obj = creator.create();
|
||||||
|
} else {
|
||||||
|
Object[] cps = new Object[this.constructorParameters.length];
|
||||||
|
for (int i = 0; i < constructorAttrs.length; i++) {
|
||||||
|
Attribute<T, Serializable> attr = constructorAttrs[i];
|
||||||
|
if (attr == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cps[i] = values[++index];
|
||||||
|
}
|
||||||
|
obj = creator.create(cps);
|
||||||
|
}
|
||||||
|
if (unconstructorAttrs != null) {
|
||||||
|
for (Attribute<T, Serializable> attr : unconstructorAttrs) {
|
||||||
|
if (attr == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
attr.set(obj, values[++index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Serializable getFieldValue(Attribute<T, Serializable> attr, final EntityInfo.DataResultSetRow row, int index) {
|
||||||
|
return row.getObject(attr, index, index > 0 ? null : this.getSQLColumn(null, attr.field()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据field字段名获取数据库对应的字段名
|
||||||
|
*
|
||||||
|
* @param tabalis 表别名
|
||||||
|
* @param fieldname 字段名
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String getSQLColumn(String tabalis, String fieldname) {
|
||||||
|
return this.aliasmap == null ? (tabalis == null ? fieldname : (tabalis + '.' + fieldname))
|
||||||
|
: (tabalis == null ? aliasmap.getOrDefault(fieldname, fieldname) : (tabalis + '.' + aliasmap.getOrDefault(fieldname, fieldname)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasConstructorAttribute() {
|
||||||
|
return constructorAttributes != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Creator<T> getCreator() {
|
||||||
|
return creator;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -55,20 +55,11 @@ public final class EntityInfo<T> {
|
|||||||
final JsonConvert jsonConvert;
|
final JsonConvert jsonConvert;
|
||||||
|
|
||||||
//Entity构建器
|
//Entity构建器
|
||||||
private final Creator<T> creator;
|
private final EntityBuilder<T> builder;
|
||||||
|
|
||||||
//Entity数值构建器
|
//Entity数值构建器
|
||||||
private final IntFunction<T[]> arrayer;
|
private final IntFunction<T[]> arrayer;
|
||||||
|
|
||||||
//Entity构建器参数
|
|
||||||
private final String[] constructorParameters;
|
|
||||||
|
|
||||||
//Entity构建器参数Attribute, 数组个数与constructorParameters相同
|
|
||||||
final Attribute<T, Serializable>[] constructorAttributes;
|
|
||||||
|
|
||||||
//Entity构建器参数Attribute
|
|
||||||
final Attribute<T, Serializable>[] unconstructorAttributes;
|
|
||||||
|
|
||||||
//主键
|
//主键
|
||||||
final Attribute<T, Serializable> primary;
|
final Attribute<T, Serializable> primary;
|
||||||
|
|
||||||
@@ -376,12 +367,12 @@ public final class EntityInfo<T> {
|
|||||||
this.tableStrategy = dts;
|
this.tableStrategy = dts;
|
||||||
|
|
||||||
this.arrayer = Creator.arrayFunction(type);
|
this.arrayer = Creator.arrayFunction(type);
|
||||||
this.creator = Creator.create(type);
|
Creator creator = Creator.create(type);
|
||||||
String[] cps = null;
|
String[] cps = null;
|
||||||
try {
|
try {
|
||||||
Method cm = this.creator.getClass().getMethod("create", Object[].class);
|
Method cm = creator.getClass().getMethod("create", Object[].class);
|
||||||
RedkaleClassLoader.putReflectionPublicMethods(this.creator.getClass().getName());
|
RedkaleClassLoader.putReflectionPublicMethods(creator.getClass().getName());
|
||||||
RedkaleClassLoader.putReflectionMethod(this.creator.getClass().getName(), cm);
|
RedkaleClassLoader.putReflectionMethod(creator.getClass().getName(), cm);
|
||||||
ConstructorParameters cp = cm.getAnnotation(ConstructorParameters.class);
|
ConstructorParameters cp = cm.getAnnotation(ConstructorParameters.class);
|
||||||
if (cp != null && cp.value().length > 0) {
|
if (cp != null && cp.value().length > 0) {
|
||||||
cps = cp.value();
|
cps = cp.value();
|
||||||
@@ -394,7 +385,7 @@ public final class EntityInfo<T> {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.log(Level.SEVERE, type + " cannot find ConstructorParameters Creator", e);
|
logger.log(Level.SEVERE, type + " cannot find ConstructorParameters Creator", e);
|
||||||
}
|
}
|
||||||
this.constructorParameters = cps;
|
String[] constructorParameters = cps;
|
||||||
Attribute idAttr0 = null;
|
Attribute idAttr0 = null;
|
||||||
Map<String, String> aliasmap0 = null;
|
Map<String, String> aliasmap0 = null;
|
||||||
Class cltmp = type;
|
Class cltmp = type;
|
||||||
@@ -528,31 +519,33 @@ public final class EntityInfo<T> {
|
|||||||
this.updateEntityAttributes = Utility.append(this.updateAttributes, this.primary);
|
this.updateEntityAttributes = Utility.append(this.updateAttributes, this.primary);
|
||||||
this.updateEntityColumns = Utility.append(this.updateColumns, this.primaryColumn);
|
this.updateEntityColumns = Utility.append(this.updateColumns, this.primaryColumn);
|
||||||
|
|
||||||
if (this.constructorParameters == null) {
|
Attribute<T, Serializable>[] constructorAttributes;
|
||||||
this.constructorAttributes = null;
|
Attribute<T, Serializable>[] unconstructorAttributes;
|
||||||
this.unconstructorAttributes = null;
|
if (constructorParameters == null) {
|
||||||
|
constructorAttributes = null;
|
||||||
|
unconstructorAttributes = null;
|
||||||
} else {
|
} else {
|
||||||
this.constructorAttributes = new Attribute[this.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 < this.constructorParameters.length; i++) {
|
for (int i = 0; i < constructorParameters.length; i++) {
|
||||||
if (attr.field().equals(this.constructorParameters[i])) {
|
if (attr.field().equals(constructorParameters[i])) {
|
||||||
pos = i;
|
pos = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pos >= 0) {
|
if (pos >= 0) {
|
||||||
this.constructorAttributes[pos] = attr;
|
constructorAttributes[pos] = attr;
|
||||||
newquerycols1.add(queryCols.get(queryAttrs.indexOf(attr)));
|
newquerycols1.add(queryCols.get(queryAttrs.indexOf(attr)));
|
||||||
} else {
|
} else {
|
||||||
unconstructorAttrs.add(attr);
|
unconstructorAttrs.add(attr);
|
||||||
newquerycols2.add(queryCols.get(queryAttrs.indexOf(attr)));
|
newquerycols2.add(queryCols.get(queryAttrs.indexOf(attr)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.unconstructorAttributes = unconstructorAttrs.toArray(new Attribute[unconstructorAttrs.size()]);
|
unconstructorAttributes = unconstructorAttrs.toArray(new Attribute[unconstructorAttrs.size()]);
|
||||||
newquerycols1.addAll(newquerycols2);
|
newquerycols1.addAll(newquerycols2);
|
||||||
queryCols = newquerycols1;
|
queryCols = newquerycols1;
|
||||||
List<Attribute<T, Serializable>> newqueryattrs = new ArrayList<>();
|
List<Attribute<T, Serializable>> newqueryattrs = new ArrayList<>();
|
||||||
@@ -569,6 +562,8 @@ 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);
|
||||||
|
|
||||||
if (table != null) {
|
if (table != null) {
|
||||||
StringBuilder querydb = new StringBuilder();
|
StringBuilder querydb = new StringBuilder();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@@ -742,13 +737,22 @@ public final class EntityInfo<T> {
|
|||||||
return cache != null && cache.isFullLoaded();
|
return cache != null && cache.isFullLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Entity构建器
|
||||||
|
*
|
||||||
|
* @return Creator
|
||||||
|
*/
|
||||||
|
public EntityBuilder<T> getBuilder() {
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取Entity构建器
|
* 获取Entity构建器
|
||||||
*
|
*
|
||||||
* @return Creator
|
* @return Creator
|
||||||
*/
|
*/
|
||||||
public Creator<T> getCreator() {
|
public Creator<T> getCreator() {
|
||||||
return creator;
|
return builder.getCreator();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1682,131 +1686,6 @@ public final class EntityInfo<T> {
|
|||||||
return String.valueOf(value);
|
return String.valueOf(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 将一行的ResultSet组装成一个Entity对象
|
|
||||||
*
|
|
||||||
* @param sels 指定字段
|
|
||||||
* @param row ResultSet
|
|
||||||
*
|
|
||||||
* @return Entity对象
|
|
||||||
*/
|
|
||||||
protected T getEntityValue(final SelectColumn sels, final DataResultSetRow row) {
|
|
||||||
if (row.wasNull()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
T obj;
|
|
||||||
Attribute<T, Serializable>[] attrs = this.queryAttributes;
|
|
||||||
if (this.constructorParameters == null) {
|
|
||||||
obj = creator.create();
|
|
||||||
} else {
|
|
||||||
Object[] cps = new Object[this.constructorParameters.length];
|
|
||||||
for (int i = 0; i < this.constructorAttributes.length; i++) {
|
|
||||||
Attribute<T, Serializable> attr = this.constructorAttributes[i];
|
|
||||||
if (sels == null || sels.test(attr.field())) {
|
|
||||||
cps[i] = getFieldValue(attr, row, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
obj = creator.create(cps);
|
|
||||||
attrs = this.unconstructorAttributes;
|
|
||||||
}
|
|
||||||
for (Attribute<T, Serializable> attr : attrs) {
|
|
||||||
if (sels == null || sels.test(attr.field())) {
|
|
||||||
attr.set(obj, getFieldValue(attr, row, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected T getFullEntityValue(final DataResultSetRow row) {
|
|
||||||
return getEntityValue(constructorAttributes, constructorAttributes == null ? queryAttributes : unconstructorAttributes, row);
|
|
||||||
}
|
|
||||||
|
|
||||||
public T getFullEntityValue(final Serializable... values) {
|
|
||||||
return getEntityValue(constructorAttributes, constructorAttributes == null ? queryAttributes : unconstructorAttributes, values);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将一行的ResultSet组装成一个Entity对象
|
|
||||||
*
|
|
||||||
* @param constructorAttrs 构建函数的Attribute数组, 大小必须与this.constructorAttributes相同
|
|
||||||
* @param unconstructorAttrs 非构建函数的Attribute数组
|
|
||||||
* @param row ResultSet
|
|
||||||
*
|
|
||||||
* @return Entity对象
|
|
||||||
*/
|
|
||||||
protected T getEntityValue(final Attribute<T, Serializable>[] constructorAttrs, final Attribute<T, Serializable>[] unconstructorAttrs, final DataResultSetRow row) {
|
|
||||||
if (row.wasNull()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
T obj;
|
|
||||||
int index = 0;
|
|
||||||
if (this.constructorParameters == null) {
|
|
||||||
obj = creator.create();
|
|
||||||
} else {
|
|
||||||
Object[] cps = new Object[this.constructorParameters.length];
|
|
||||||
for (int i = 0; i < constructorAttrs.length; i++) {
|
|
||||||
Attribute<T, Serializable> attr = constructorAttrs[i];
|
|
||||||
if (attr == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
cps[i] = getFieldValue(attr, row, ++index);
|
|
||||||
}
|
|
||||||
obj = creator.create(cps);
|
|
||||||
}
|
|
||||||
if (unconstructorAttrs != null) {
|
|
||||||
for (Attribute<T, Serializable> attr : unconstructorAttrs) {
|
|
||||||
if (attr == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
attr.set(obj, getFieldValue(attr, row, ++index));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将一行的ResultSet组装成一个Entity对象
|
|
||||||
*
|
|
||||||
* @param constructorAttrs 构建函数的Attribute数组, 大小必须与this.constructorAttributes相同
|
|
||||||
* @param unconstructorAttrs 非构建函数的Attribute数组
|
|
||||||
* @param values 字段值集合
|
|
||||||
*
|
|
||||||
* @return Entity对象
|
|
||||||
*/
|
|
||||||
protected T getEntityValue(final Attribute<T, Serializable>[] constructorAttrs, final Attribute<T, Serializable>[] unconstructorAttrs, final Serializable... values) {
|
|
||||||
if (values == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
T obj;
|
|
||||||
int index = -1;
|
|
||||||
if (this.constructorParameters == null) {
|
|
||||||
obj = creator.create();
|
|
||||||
} else {
|
|
||||||
Object[] cps = new Object[this.constructorParameters.length];
|
|
||||||
for (int i = 0; i < constructorAttrs.length; i++) {
|
|
||||||
Attribute<T, Serializable> attr = constructorAttrs[i];
|
|
||||||
if (attr == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
cps[i] = values[++index];
|
|
||||||
}
|
|
||||||
obj = creator.create(cps);
|
|
||||||
}
|
|
||||||
if (unconstructorAttrs != null) {
|
|
||||||
for (Attribute<T, Serializable> attr : unconstructorAttrs) {
|
|
||||||
if (attr == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
attr.set(obj, values[++index]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
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()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getClass().getSimpleName() + "(" + type.getName() + ")@" + Objects.hashCode(this);
|
return getClass().getSimpleName() + "(" + type.getName() + ")@" + Objects.hashCode(this);
|
||||||
|
|||||||
Reference in New Issue
Block a user