EntityBuilder优化

This commit is contained in:
redkale
2023-07-25 20:00:25 +08:00
parent e86638e490
commit 70764f1ea4
4 changed files with 219 additions and 91 deletions

View File

@@ -2465,7 +2465,7 @@ public class DataJdbcSource extends AbstractDataSqlSource {
final SourceConnection conn = readPool.pollConnection();
try {
if (logger.isLoggable(Level.FINEST)) {
logger.finest("direct query sql=" + sql);
logger.finest("executeQuery sql=" + sql);
}
final Statement stmt = conn.createQueryStatement();
//final PreparedStatement prestmt = conn.prepareStatement(sql);

View File

@@ -6,6 +6,7 @@
package org.redkale.source;
import java.io.Serializable;
import java.lang.reflect.Type;
import java.math.*;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.*;
@@ -45,6 +46,117 @@ public interface DataResultSet extends EntityInfo.DataResultSetRow {
public void close();
public static Serializable formatColumnValue(Class t, Object o) {
return formatColumnValue(t, null, o);
}
public static Serializable formatColumnValue(Class t, Type genericType, Object o) {
if (t == byte[].class) {
return (byte[]) o;
} else {
if (t.isPrimitive()) {
if (o != null) {
if (t == int.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 == char.class) {
o = (char) ((Number) o).intValue();
} else if (t == boolean.class) {
o = (Boolean) o;
}
} else if (t == int.class) {
o = 0;
} else if (t == long.class) {
o = 0L;
} else if (t == short.class) {
o = (short) 0;
} else if (t == float.class) {
o = 0.0f;
} else if (t == double.class) {
o = 0.0d;
} else if (t == byte.class) {
o = (byte) 0;
} else if (t == boolean.class) {
o = false;
} else if (t == char.class) {
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) {
if (o != null) {
o = new AtomicInteger(((Number) o).intValue());
} else {
o = new AtomicInteger();
}
} else if (t == AtomicLong.class) {
if (o != null) {
o = new AtomicLong(((Number) o).longValue());
} else {
o = new AtomicLong();
}
} else if (t == LongAdder.class) {
if (o != null) {
LongAdder v = new LongAdder();
v.add(((Number) o).longValue());
o = v;
} else {
o = new LongAdder();
}
} else if (t == BigInteger.class) {
if (o != null && !(o instanceof BigInteger)) {
if (o instanceof byte[]) {
o = new BigInteger((byte[]) o);
} else {
o = new BigInteger(o.toString(), 10);
}
}
} else if (t == BigDecimal.class) {
if (o != null && !(o instanceof BigDecimal)) {
if (o instanceof byte[]) {
o = new BigDecimal(new String((byte[]) o));
} else {
o = new BigDecimal(o.toString());
}
}
} else if (t == String.class) {
if (o == null) {
o = "";
} else if (o instanceof byte[]) {
o = new String((byte[]) o, StandardCharsets.UTF_8);
} else {
o = o.toString();
}
} else if (o != null && !t.isAssignableFrom(o.getClass()) && o instanceof CharSequence) {
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;
@@ -67,89 +179,7 @@ public interface DataResultSet extends EntityInfo.DataResultSetRow {
}
} else {
o = (Serializable) (index > 0 ? row.getObject(index) : row.getObject(column));
if (t.isPrimitive()) {
if (o != null) {
if (t == int.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 == char.class) {
o = (char) ((Number) o).intValue();
} else if (t == boolean.class) {
o = (Boolean) o;
}
} else if (t == int.class) {
o = 0;
} else if (t == long.class) {
o = 0L;
} else if (t == short.class) {
o = (short) 0;
} else if (t == float.class) {
o = 0.0f;
} else if (t == double.class) {
o = 0.0d;
} else if (t == byte.class) {
o = (byte) 0;
} else if (t == boolean.class) {
o = false;
} else if (t == char.class) {
o = (char) 0;
}
} else if (t == AtomicInteger.class) {
if (o != null) {
o = new AtomicInteger(((Number) o).intValue());
} else {
o = new AtomicInteger();
}
} else if (t == AtomicLong.class) {
if (o != null) {
o = new AtomicLong(((Number) o).longValue());
} else {
o = new AtomicLong();
}
} else if (t == LongAdder.class) {
if (o != null) {
LongAdder v = new LongAdder();
v.add(((Number) o).longValue());
o = v;
} else {
o = new LongAdder();
}
} else if (t == BigInteger.class) {
if (o != null && !(o instanceof BigInteger)) {
if (o instanceof byte[]) {
o = new BigInteger((byte[]) o);
} else {
o = new BigInteger(o.toString(), 10);
}
}
} else if (t == BigDecimal.class) {
if (o != null && !(o instanceof BigDecimal)) {
if (o instanceof byte[]) {
o = new BigDecimal(new String((byte[]) o));
} else {
o = new BigDecimal(o.toString());
}
}
} else if (t == String.class) {
if (o == null) {
o = "";
} else if (o instanceof byte[]) {
o = new String((byte[]) o, StandardCharsets.UTF_8);
} else {
o = o.toString();
}
} 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 = formatColumnValue(t, attr.genericType(), o);
}
} catch (Exception e) {
throw new SourceException(row.getEntityInfo() + "." + attr.field() + ".value=" + o + ": " + e.getMessage(), e.getCause());

View File

@@ -3,6 +3,7 @@
*/
package org.redkale.source;
import java.util.*;
import java.util.function.Function;
/**
@@ -23,4 +24,28 @@ public interface DataSqlSource extends DataSource {
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);
});
}
}

View File

@@ -10,6 +10,7 @@ import java.util.concurrent.ConcurrentHashMap;
import org.redkale.annotation.Nullable;
import org.redkale.convert.ConvertDisabled;
import org.redkale.persistence.*;
import org.redkale.source.EntityInfo.DataResultSetRow;
import org.redkale.util.*;
/**
@@ -29,7 +30,7 @@ public class EntityBuilder<T> {
@Nullable
private final String[] constructorParameters;
//key是field的name value是Column的别名数据库表的字段名
//key:类字段名, value数据库字段名
//只有field.name 与 Column.name不同才存放在aliasmap里.
@Nullable
private final Map<String, String> aliasmap;
@@ -42,7 +43,11 @@ public class EntityBuilder<T> {
@Nullable
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一致
private final Attribute<T, Serializable>[] attributes;
@@ -51,7 +56,7 @@ public class EntityBuilder<T> {
Map<String, String> aliasmap, String[] constructorParameters,
Attribute<T, Serializable>[] constructorAttributes,
Attribute<T, Serializable>[] unconstructorAttributes,
HashMap<String, Attribute<T, Serializable>> attributeMap,
Map<String, Attribute<T, Serializable>> attributeMap,
Attribute<T, Serializable>[] queryAttributes) {
this.creator = creator;
this.aliasmap = aliasmap;
@@ -60,6 +65,8 @@ public class EntityBuilder<T> {
this.unconstructorAttributes = unconstructorAttributes;
this.attributeMap = attributeMap;
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) {
@@ -164,6 +171,64 @@ public class EntityBuilder<T> {
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对象
*
@@ -172,7 +237,7 @@ public class EntityBuilder<T> {
*
* @return Entity对象
*/
public T getEntityValue(final SelectColumn sels, final EntityInfo.DataResultSetRow row) {
public T getEntityValue(final SelectColumn sels, final DataResultSetRow row) {
if (row.wasNull()) {
return null;
}
@@ -199,7 +264,15 @@ public class EntityBuilder<T> {
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);
}
@@ -216,7 +289,7 @@ public class EntityBuilder<T> {
*
* @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()) {
return null;
}
@@ -285,7 +358,7 @@ public class EntityBuilder<T> {
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()));
}