EntityBuilder优化
This commit is contained in:
@@ -2465,7 +2465,7 @@ public class DataJdbcSource extends AbstractDataSqlSource {
|
|||||||
final SourceConnection conn = readPool.pollConnection();
|
final SourceConnection conn = readPool.pollConnection();
|
||||||
try {
|
try {
|
||||||
if (logger.isLoggable(Level.FINEST)) {
|
if (logger.isLoggable(Level.FINEST)) {
|
||||||
logger.finest("direct query sql=" + sql);
|
logger.finest("executeQuery sql=" + sql);
|
||||||
}
|
}
|
||||||
final Statement stmt = conn.createQueryStatement();
|
final Statement stmt = conn.createQueryStatement();
|
||||||
//final PreparedStatement prestmt = conn.prepareStatement(sql);
|
//final PreparedStatement prestmt = conn.prepareStatement(sql);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.redkale.source;
|
package org.redkale.source;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
import java.math.*;
|
import java.math.*;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.concurrent.atomic.*;
|
import java.util.concurrent.atomic.*;
|
||||||
@@ -45,28 +46,14 @@ public interface DataResultSet extends EntityInfo.DataResultSetRow {
|
|||||||
|
|
||||||
public void close();
|
public void close();
|
||||||
|
|
||||||
public static <T> Serializable getRowColumnValue(final EntityInfo.DataResultSetRow row, Attribute<T, Serializable> attr, int index, String column) {
|
public static Serializable formatColumnValue(Class t, Object o) {
|
||||||
final Class t = attr.type();
|
return formatColumnValue(t, null, o);
|
||||||
Serializable o = null;
|
|
||||||
try {
|
|
||||||
if (t == byte[].class) {
|
|
||||||
Object blob = index > 0 ? row.getObject(index) : row.getObject(column);
|
|
||||||
if (blob == null) {
|
|
||||||
o = null;
|
|
||||||
} else { //不支持超过2G的数据
|
|
||||||
// if (blob instanceof java.sql.Blob) {
|
|
||||||
// java.sql.Blob b = (java.sql.Blob) blob;
|
|
||||||
// try {
|
|
||||||
// o = b.getBytes(1, (int) b.length());
|
|
||||||
// } catch (Exception e) { //一般不会发生
|
|
||||||
// o = null;
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
o = (byte[]) blob;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Serializable formatColumnValue(Class t, Type genericType, Object o) {
|
||||||
|
if (t == byte[].class) {
|
||||||
|
return (byte[]) o;
|
||||||
} else {
|
} else {
|
||||||
o = (Serializable) (index > 0 ? row.getObject(index) : row.getObject(column));
|
|
||||||
if (t.isPrimitive()) {
|
if (t.isPrimitive()) {
|
||||||
if (o != null) {
|
if (o != null) {
|
||||||
if (t == int.class) {
|
if (t == int.class) {
|
||||||
@@ -103,6 +90,22 @@ public interface DataResultSet extends EntityInfo.DataResultSetRow {
|
|||||||
} else if (t == char.class) {
|
} else if (t == char.class) {
|
||||||
o = (char) 0;
|
o = (char) 0;
|
||||||
}
|
}
|
||||||
|
} else if (t == Integer.class) {
|
||||||
|
o = ((Number) o).intValue();
|
||||||
|
} else if (t == Long.class) {
|
||||||
|
o = ((Number) o).longValue();
|
||||||
|
} else if (t == Short.class) {
|
||||||
|
o = ((Number) o).shortValue();
|
||||||
|
} else if (t == Float.class) {
|
||||||
|
o = ((Number) o).floatValue();
|
||||||
|
} else if (t == Double.class) {
|
||||||
|
o = ((Number) o).doubleValue();
|
||||||
|
} else if (t == Byte.class) {
|
||||||
|
o = ((Number) o).byteValue();
|
||||||
|
} else if (t == Character.class) {
|
||||||
|
o = (char) ((Number) o).intValue();
|
||||||
|
} else if (t == Boolean.class) {
|
||||||
|
o = (Boolean) o;
|
||||||
} else if (t == AtomicInteger.class) {
|
} else if (t == AtomicInteger.class) {
|
||||||
if (o != null) {
|
if (o != null) {
|
||||||
o = new AtomicInteger(((Number) o).intValue());
|
o = new AtomicInteger(((Number) o).intValue());
|
||||||
@@ -148,9 +151,36 @@ public interface DataResultSet extends EntityInfo.DataResultSetRow {
|
|||||||
o = o.toString();
|
o = o.toString();
|
||||||
}
|
}
|
||||||
} else if (o != null && !t.isAssignableFrom(o.getClass()) && o instanceof CharSequence) {
|
} else if (o != null && !t.isAssignableFrom(o.getClass()) && o instanceof CharSequence) {
|
||||||
o = ((CharSequence) o).length() == 0 ? null : JsonConvert.root().convertFrom(attr.genericType(), o.toString());
|
o = ((CharSequence) o).length() == 0 ? null : JsonConvert.root().convertFrom(genericType == null ? t : genericType, o.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return (Serializable) o;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Serializable getRowColumnValue(final EntityInfo.DataResultSetRow row, Attribute<T, Serializable> attr, int index, String column) {
|
||||||
|
final Class t = attr.type();
|
||||||
|
Serializable o = null;
|
||||||
|
try {
|
||||||
|
if (t == byte[].class) {
|
||||||
|
Object blob = index > 0 ? row.getObject(index) : row.getObject(column);
|
||||||
|
if (blob == null) {
|
||||||
|
o = null;
|
||||||
|
} else { //不支持超过2G的数据
|
||||||
|
// if (blob instanceof java.sql.Blob) {
|
||||||
|
// java.sql.Blob b = (java.sql.Blob) blob;
|
||||||
|
// try {
|
||||||
|
// o = b.getBytes(1, (int) b.length());
|
||||||
|
// } catch (Exception e) { //一般不会发生
|
||||||
|
// o = null;
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
o = (byte[]) blob;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
o = (Serializable) (index > 0 ? row.getObject(index) : row.getObject(column));
|
||||||
|
o = formatColumnValue(t, attr.genericType(), o);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new SourceException(row.getEntityInfo() + "." + attr.field() + ".value=" + o + ": " + e.getMessage(), e.getCause());
|
throw new SourceException(row.getEntityInfo() + "." + attr.field() + ".value=" + o + ": " + e.getMessage(), e.getCause());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.source;
|
package org.redkale.source;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -23,4 +24,28 @@ public interface DataSqlSource extends DataSource {
|
|||||||
|
|
||||||
public <V> V executeQuery(String sql, Function<DataResultSet, V> handler);
|
public <V> V executeQuery(String sql, Function<DataResultSet, V> handler);
|
||||||
|
|
||||||
|
default <V> V executeQueryOne(Class<V> type, String sql) {
|
||||||
|
return executeQuery(sql, rset -> {
|
||||||
|
if (!rset.next()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (type.isPrimitive() || type == byte[].class || type.getName().startsWith("java.")) {
|
||||||
|
return (V) DataResultSet.formatColumnValue(type, rset.getObject(1));
|
||||||
|
}
|
||||||
|
return EntityBuilder.load(type).getObjectValue(rset);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
default <V> List<V> executeQueryList(Class<V> type, String sql) {
|
||||||
|
return executeQuery(sql, rset -> {
|
||||||
|
if (type.isPrimitive() || type == byte[].class || type.getName().startsWith("java.")) {
|
||||||
|
List<V> list = new ArrayList<>();
|
||||||
|
while (rset.next()) {
|
||||||
|
list.add(rset.wasNull() ? null : (V) DataResultSet.formatColumnValue(type, rset.getObject(1)));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
return EntityBuilder.load(type).getObjectList(rset);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
import org.redkale.annotation.Nullable;
|
import org.redkale.annotation.Nullable;
|
||||||
import org.redkale.convert.ConvertDisabled;
|
import org.redkale.convert.ConvertDisabled;
|
||||||
import org.redkale.persistence.*;
|
import org.redkale.persistence.*;
|
||||||
|
import org.redkale.source.EntityInfo.DataResultSetRow;
|
||||||
import org.redkale.util.*;
|
import org.redkale.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,7 +30,7 @@ public class EntityBuilder<T> {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private final String[] constructorParameters;
|
private final String[] constructorParameters;
|
||||||
|
|
||||||
//key是field的name, value是Column的别名,即数据库表的字段名
|
//key:类字段名, value:数据库字段名
|
||||||
//只有field.name 与 Column.name不同才存放在aliasmap里.
|
//只有field.name 与 Column.name不同才存放在aliasmap里.
|
||||||
@Nullable
|
@Nullable
|
||||||
private final Map<String, String> aliasmap;
|
private final Map<String, String> aliasmap;
|
||||||
@@ -42,7 +43,11 @@ public class EntityBuilder<T> {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private final Attribute<T, Serializable>[] unconstructorAttributes;
|
private final Attribute<T, Serializable>[] unconstructorAttributes;
|
||||||
|
|
||||||
private final HashMap<String, Attribute<T, Serializable>> attributeMap;
|
//key:类字段名
|
||||||
|
private final Map<String, Attribute<T, Serializable>> attributeMap;
|
||||||
|
|
||||||
|
//key:数据库字段名
|
||||||
|
private final Map<String, Attribute<T, Serializable>> sqlAttrMap;
|
||||||
|
|
||||||
//数据库中所有字段, 顺序必须与querySqlColumns、querySqlColumnSequence一致
|
//数据库中所有字段, 顺序必须与querySqlColumns、querySqlColumnSequence一致
|
||||||
private final Attribute<T, Serializable>[] attributes;
|
private final Attribute<T, Serializable>[] attributes;
|
||||||
@@ -51,7 +56,7 @@ public class EntityBuilder<T> {
|
|||||||
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,
|
||||||
HashMap<String, Attribute<T, Serializable>> attributeMap,
|
Map<String, Attribute<T, Serializable>> attributeMap,
|
||||||
Attribute<T, Serializable>[] queryAttributes) {
|
Attribute<T, Serializable>[] queryAttributes) {
|
||||||
this.creator = creator;
|
this.creator = creator;
|
||||||
this.aliasmap = aliasmap;
|
this.aliasmap = aliasmap;
|
||||||
@@ -60,6 +65,8 @@ public class EntityBuilder<T> {
|
|||||||
this.unconstructorAttributes = unconstructorAttributes;
|
this.unconstructorAttributes = unconstructorAttributes;
|
||||||
this.attributeMap = attributeMap;
|
this.attributeMap = attributeMap;
|
||||||
this.attributes = queryAttributes;
|
this.attributes = queryAttributes;
|
||||||
|
this.sqlAttrMap = new HashMap<>();
|
||||||
|
attributeMap.forEach((k, v) -> sqlAttrMap.put(getSQLColumn(null, k), v));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> EntityBuilder<T> load(Class<T> type) {
|
public static <T> EntityBuilder<T> load(Class<T> type) {
|
||||||
@@ -164,6 +171,64 @@ public class EntityBuilder<T> {
|
|||||||
unconstructorAttributes, attributeMap, queryAttrs.toArray(new Attribute[queryAttrs.size()]));
|
unconstructorAttributes, attributeMap, queryAttrs.toArray(new Attribute[queryAttrs.size()]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<T> getObjectList(final DataResultSet rset) {
|
||||||
|
List<T> list = new ArrayList<>();
|
||||||
|
List<String> sqlColumns = rset.getColumnLabels();
|
||||||
|
while (rset.next()) {
|
||||||
|
list.add(getObjectValue(sqlColumns, rset));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getObjectValue(final DataResultSetRow row) {
|
||||||
|
return getObjectValue(null, row);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected T getObjectValue(List<String> sqlColumns, final DataResultSetRow row) {
|
||||||
|
if (row.wasNull()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
T obj;
|
||||||
|
if (sqlColumns == null) {
|
||||||
|
sqlColumns = row.getColumnLabels();
|
||||||
|
}
|
||||||
|
Map<String, Attribute<T, Serializable>> attrs = this.sqlAttrMap;
|
||||||
|
if (this.constructorParameters == null) {
|
||||||
|
obj = creator.create();
|
||||||
|
for (String sqlCol : sqlColumns) {
|
||||||
|
Attribute<T, Serializable> attr = attrs.get(sqlCol);
|
||||||
|
if (attr != null) { //兼容返回的字段不存在类中
|
||||||
|
attr.set(obj, getFieldValue(attr, row, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Object[] cps = new Object[this.constructorParameters.length];
|
||||||
|
for (int i = 0; i < this.constructorAttributes.length; i++) {
|
||||||
|
Attribute<T, Serializable> attr = this.constructorAttributes[i];
|
||||||
|
String sqlCol = getSQLColumn(null, attr.field());
|
||||||
|
if (sqlColumns.contains(sqlCol)) {
|
||||||
|
cps[i] = getFieldValue(attr, row, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
obj = creator.create(cps);
|
||||||
|
for (Attribute<T, Serializable> attr : this.unconstructorAttributes) {
|
||||||
|
String sqlCol = getSQLColumn(null, attr.field());
|
||||||
|
if (sqlColumns.contains(sqlCol)) {
|
||||||
|
attr.set(obj, getFieldValue(attr, row, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> getEntityList(final SelectColumn sels, final DataResultSet rset) {
|
||||||
|
List<T> list = new ArrayList<>();
|
||||||
|
while (rset.next()) {
|
||||||
|
list.add(getEntityValue(sels, rset));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将一行的ResultSet组装成一个Entity对象
|
* 将一行的ResultSet组装成一个Entity对象
|
||||||
*
|
*
|
||||||
@@ -172,7 +237,7 @@ public class EntityBuilder<T> {
|
|||||||
*
|
*
|
||||||
* @return Entity对象
|
* @return Entity对象
|
||||||
*/
|
*/
|
||||||
public T getEntityValue(final SelectColumn sels, final EntityInfo.DataResultSetRow row) {
|
public T getEntityValue(final SelectColumn sels, final DataResultSetRow row) {
|
||||||
if (row.wasNull()) {
|
if (row.wasNull()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -199,7 +264,15 @@ public class EntityBuilder<T> {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T getFullEntityValue(final EntityInfo.DataResultSetRow row) {
|
public List<T> getFullEntityList(final DataResultSet rset) {
|
||||||
|
List<T> list = new ArrayList<>();
|
||||||
|
while (rset.next()) {
|
||||||
|
list.add(getFullEntityValue(rset));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getFullEntityValue(final DataResultSetRow row) {
|
||||||
return getEntityValue(constructorAttributes, constructorAttributes == null ? attributes : unconstructorAttributes, row);
|
return getEntityValue(constructorAttributes, constructorAttributes == null ? attributes : unconstructorAttributes, row);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +289,7 @@ public class EntityBuilder<T> {
|
|||||||
*
|
*
|
||||||
* @return Entity对象
|
* @return Entity对象
|
||||||
*/
|
*/
|
||||||
protected T getEntityValue(final Attribute<T, Serializable>[] constructorAttrs, final Attribute<T, Serializable>[] unconstructorAttrs, final EntityInfo.DataResultSetRow row) {
|
protected T getEntityValue(final Attribute<T, Serializable>[] constructorAttrs, final Attribute<T, Serializable>[] unconstructorAttrs, final DataResultSetRow row) {
|
||||||
if (row.wasNull()) {
|
if (row.wasNull()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -285,7 +358,7 @@ public class EntityBuilder<T> {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Serializable getFieldValue(Attribute<T, Serializable> attr, final EntityInfo.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()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user