DataSqlMapper
This commit is contained in:
@@ -18,6 +18,9 @@ import org.redkale.util.Sheet;
|
||||
|
||||
/**
|
||||
* 类似Mybatis的Mapper接口类, 接口系列和DataSource相似度高 <br>
|
||||
* 自定义的sql接口的返回结果类型只能是:
|
||||
* void/基本数据类型/JavaBean/Map/List/Sheet <br>
|
||||
* 异步接口返回的是泛型为以上类型的CompletableFuture
|
||||
*
|
||||
* <p>
|
||||
* 详情见: https://redkale.org
|
||||
|
||||
@@ -130,8 +130,10 @@ public interface DataSqlSource extends DataSource {
|
||||
*/
|
||||
public <V> CompletableFuture<V> nativeQueryAsync(String sql, BiConsumer<Object, Object> consumer, Function<DataResultSet, V> handler, Map<String, Object> params);
|
||||
|
||||
@AsmDepends
|
||||
public <V> Sheet<V> nativeQuerySheet(Class<V> type, String sql, Flipper flipper, Map<String, Object> params);
|
||||
|
||||
@AsmDepends
|
||||
public <V> CompletableFuture<Sheet<V>> nativeQuerySheetAsync(Class<V> type, String sql, Flipper flipper, Map<String, Object> params);
|
||||
|
||||
//----------------------------- 无参数 -----------------------------
|
||||
@@ -143,30 +145,37 @@ public interface DataSqlSource extends DataSource {
|
||||
return nativeQueryAsync(sql, null, handler);
|
||||
}
|
||||
|
||||
@AsmDepends
|
||||
default <V> V nativeQueryOne(Class<V> type, String sql) {
|
||||
return nativeQuery(sql, rset -> EntityBuilder.getOneValue(type, rset));
|
||||
}
|
||||
|
||||
@AsmDepends
|
||||
default <V> CompletableFuture<V> nativeQueryOneAsync(Class<V> type, String sql) {
|
||||
return nativeQueryAsync(sql, rset -> EntityBuilder.getOneValue(type, rset));
|
||||
}
|
||||
|
||||
@AsmDepends
|
||||
default <V> List<V> nativeQueryList(Class<V> type, String sql) {
|
||||
return nativeQuery(sql, rset -> EntityBuilder.getListValue(type, rset));
|
||||
}
|
||||
|
||||
@AsmDepends
|
||||
default <V> CompletableFuture<List<V>> nativeQueryListAsync(Class<V> type, String sql) {
|
||||
return nativeQueryAsync(sql, rset -> EntityBuilder.getListValue(type, rset));
|
||||
}
|
||||
|
||||
@AsmDepends
|
||||
default <V> Sheet<V> nativeQuerySheet(Class<V> type, String sql, Flipper flipper) {
|
||||
return nativeQuerySheet(type, sql, flipper, Collections.emptyMap());
|
||||
}
|
||||
|
||||
@AsmDepends
|
||||
default <V> CompletableFuture<Sheet<V>> nativeQuerySheetAsync(Class<V> type, String sql, Flipper flipper) {
|
||||
return nativeQuerySheetAsync(type, sql, flipper, Collections.emptyMap());
|
||||
}
|
||||
|
||||
@AsmDepends
|
||||
default <K, V> Map<K, V> nativeQueryMap(Class<K> keyType, Class<V> valType, String sql) {
|
||||
return nativeQuery(sql, rset -> {
|
||||
Map<K, V> map = new LinkedHashMap<K, V>();
|
||||
@@ -179,6 +188,7 @@ public interface DataSqlSource extends DataSource {
|
||||
});
|
||||
}
|
||||
|
||||
@AsmDepends
|
||||
default <K, V> CompletableFuture<Map<K, V>> nativeQueryMapAsync(Class<K> keyType, Class<V> valType, String sql) {
|
||||
return nativeQueryAsync(sql, rset -> {
|
||||
Map<K, V> map = new LinkedHashMap<K, V>();
|
||||
@@ -216,6 +226,7 @@ public interface DataSqlSource extends DataSource {
|
||||
return nativeQueryAsync(sql, null, handler, params);
|
||||
}
|
||||
|
||||
@AsmDepends
|
||||
default <V> V nativeQueryOne(Class<V> type, String sql, Map<String, Object> params) {
|
||||
return nativeQuery(sql, rset -> {
|
||||
if (!rset.next()) {
|
||||
@@ -229,6 +240,7 @@ public interface DataSqlSource extends DataSource {
|
||||
}, params);
|
||||
}
|
||||
|
||||
@AsmDepends
|
||||
default <V> CompletableFuture<V> nativeQueryOneAsync(Class<V> type, String sql, Map<String, Object> params) {
|
||||
return nativeQueryAsync(sql, rset -> {
|
||||
if (!rset.next()) {
|
||||
@@ -242,6 +254,7 @@ public interface DataSqlSource extends DataSource {
|
||||
}, params);
|
||||
}
|
||||
|
||||
@AsmDepends
|
||||
default <V> List<V> nativeQueryList(Class<V> type, String sql, Map<String, Object> params) {
|
||||
return nativeQuery(sql, rset -> {
|
||||
if (type == byte[].class || type == String.class || type.isPrimitive() || Number.class.isAssignableFrom(type)
|
||||
@@ -256,6 +269,7 @@ public interface DataSqlSource extends DataSource {
|
||||
}, params);
|
||||
}
|
||||
|
||||
@AsmDepends
|
||||
default <V> CompletableFuture<List<V>> nativeQueryListAsync(Class<V> type, String sql, Map<String, Object> params) {
|
||||
return nativeQueryAsync(sql, rset -> {
|
||||
if (type == byte[].class || type == String.class || type.isPrimitive() || Number.class.isAssignableFrom(type)
|
||||
@@ -270,6 +284,7 @@ public interface DataSqlSource extends DataSource {
|
||||
}, params);
|
||||
}
|
||||
|
||||
@AsmDepends
|
||||
default <K, V> Map<K, V> nativeQueryMap(Class<K> keyType, Class<V> valType, String sql, Map<String, Object> params) {
|
||||
return nativeQuery(sql, rset -> {
|
||||
Map<K, V> map = new LinkedHashMap<K, V>();
|
||||
@@ -282,6 +297,7 @@ public interface DataSqlSource extends DataSource {
|
||||
}, params);
|
||||
}
|
||||
|
||||
@AsmDepends
|
||||
default <K, V> CompletableFuture<Map<K, V>> nativeQueryMapAsync(Class<K> keyType, Class<V> valType, String sql, Map<String, Object> params) {
|
||||
return nativeQueryAsync(sql, rset -> {
|
||||
Map<K, V> map = new LinkedHashMap<K, V>();
|
||||
|
||||
@@ -15,27 +15,36 @@ import java.util.function.IntFunction;
|
||||
import org.redkale.asm.AnnotationVisitor;
|
||||
import org.redkale.asm.AsmMethodBean;
|
||||
import org.redkale.asm.AsmMethodBoost;
|
||||
import org.redkale.asm.AsmMethodParam;
|
||||
import org.redkale.asm.Asms;
|
||||
import org.redkale.asm.ClassWriter;
|
||||
import static org.redkale.asm.ClassWriter.COMPUTE_FRAMES;
|
||||
import org.redkale.asm.FieldVisitor;
|
||||
import org.redkale.asm.Label;
|
||||
import org.redkale.asm.MethodDebugVisitor;
|
||||
import org.redkale.asm.MethodVisitor;
|
||||
import static org.redkale.asm.Opcodes.AASTORE;
|
||||
import static org.redkale.asm.Opcodes.ACC_PRIVATE;
|
||||
import static org.redkale.asm.Opcodes.ACC_PUBLIC;
|
||||
import static org.redkale.asm.Opcodes.ACC_SUPER;
|
||||
import static org.redkale.asm.Opcodes.ALOAD;
|
||||
import static org.redkale.asm.Opcodes.ANEWARRAY;
|
||||
import static org.redkale.asm.Opcodes.ARETURN;
|
||||
import static org.redkale.asm.Opcodes.ASTORE;
|
||||
import static org.redkale.asm.Opcodes.CHECKCAST;
|
||||
import static org.redkale.asm.Opcodes.DLOAD;
|
||||
import static org.redkale.asm.Opcodes.DUP;
|
||||
import static org.redkale.asm.Opcodes.FLOAD;
|
||||
import static org.redkale.asm.Opcodes.GETFIELD;
|
||||
import static org.redkale.asm.Opcodes.ILOAD;
|
||||
import static org.redkale.asm.Opcodes.INVOKEINTERFACE;
|
||||
import static org.redkale.asm.Opcodes.INVOKESPECIAL;
|
||||
import static org.redkale.asm.Opcodes.INVOKESTATIC;
|
||||
import static org.redkale.asm.Opcodes.INVOKEVIRTUAL;
|
||||
import static org.redkale.asm.Opcodes.NEW;
|
||||
import static org.redkale.asm.Opcodes.POP;
|
||||
import static org.redkale.asm.Opcodes.LLOAD;
|
||||
import static org.redkale.asm.Opcodes.RETURN;
|
||||
import static org.redkale.asm.Opcodes.V11;
|
||||
import org.redkale.asm.Type;
|
||||
import org.redkale.convert.json.JsonObject;
|
||||
import org.redkale.persistence.Sql;
|
||||
import org.redkale.source.AbstractDataSqlSource;
|
||||
import org.redkale.source.DataNativeSqlInfo;
|
||||
@@ -43,8 +52,10 @@ import static org.redkale.source.DataNativeSqlInfo.SqlMode.SELECT;
|
||||
import org.redkale.source.DataNativeSqlParser;
|
||||
import org.redkale.source.DataSqlMapper;
|
||||
import org.redkale.source.DataSqlSource;
|
||||
import org.redkale.source.Flipper;
|
||||
import org.redkale.source.SourceException;
|
||||
import org.redkale.util.RedkaleClassLoader;
|
||||
import org.redkale.util.Sheet;
|
||||
import org.redkale.util.TypeToken;
|
||||
import org.redkale.util.Utility;
|
||||
|
||||
@@ -132,10 +143,10 @@ public final class DataSqlMapperBuilder {
|
||||
if (!Utility.equalsElement(sqlInfo.getRootParamNames(), methodBean.fieldNameList())) {
|
||||
throw new SourceException(method + " parameters not match @" + Sql.class.getSimpleName() + "(" + sql.value() + ")");
|
||||
}
|
||||
Class returnType = returnType(method);
|
||||
if (sqlInfo.getSqlMode() != SELECT) {
|
||||
if (returnType != Integer.class && returnType != int.class
|
||||
&& returnType != Void.class && returnType != void.class) {
|
||||
Class resultClass = resultClass(method);
|
||||
if (sqlInfo.getSqlMode() != SELECT) { //非SELECT语句只能返回int或void
|
||||
if (resultClass != Integer.class && resultClass != int.class
|
||||
&& resultClass != Void.class && resultClass != void.class) {
|
||||
throw new SourceException("@" + Sql.class.getSimpleName()
|
||||
+ "(" + sql.value() + ") must on return int or void method, but " + method);
|
||||
}
|
||||
@@ -144,7 +155,11 @@ public final class DataSqlMapperBuilder {
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
final String utilClassName = Utility.class.getName().replace('.', '/');
|
||||
final String sheetDesc = Type.getDescriptor(Sheet.class);
|
||||
final String flipperDesc = Type.getDescriptor(Flipper.class);
|
||||
final String entityDesc = Type.getDescriptor(entityType);
|
||||
final String sqlSourceName = DataSqlSource.class.getName().replace('.', '/');
|
||||
final String sqlSourceDesc = Type.getDescriptor(DataSqlSource.class);
|
||||
|
||||
ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
|
||||
@@ -187,46 +202,121 @@ public final class DataSqlMapperBuilder {
|
||||
}
|
||||
|
||||
//sql系列方法
|
||||
//int nativeUpdate(String sql)
|
||||
//CompletableFuture<Integer> nativeUpdateAsync(String sql)
|
||||
//int nativeUpdate(String sql, Map<String, Object> params)
|
||||
//CompletableFuture<Integer> nativeUpdateAsync(String sql, Map<String, Object> params)
|
||||
//
|
||||
//V nativeQueryOne(Class<V> type, String sql)
|
||||
//CompletableFuture<V> nativeQueryOneAsync(Class<V> type, String sql)
|
||||
//V nativeQueryOne(Class<V> type, String sql, Map<String, Object> params)
|
||||
//CompletableFuture<V> nativeQueryOneAsync(Class<V> type, String sql, Map<String, Object> params)
|
||||
//
|
||||
//Map<K, V> nativeQueryMap(Class<K> keyType, Class<V> valType, String sql, Map<String, Object> params)
|
||||
//CompletableFuture<Map<K, V>> nativeQueryMapAsync(Class<K> keyType, Class<V> valType, String sql, Map<String, Object> params)
|
||||
//
|
||||
//nativeQueryOne、nativeQueryList、nativeQuerySheet
|
||||
for (Item item : items) {
|
||||
Method method = item.method;
|
||||
DataNativeSqlInfo sqlInfo = item.sqlInfo;
|
||||
AsmMethodBean methodBean = item.methodBean;
|
||||
Sql sql = method.getAnnotation(Sql.class);
|
||||
Class resultClass = resultClass(method);
|
||||
Class[] componentTypes = resultComponentType(method);
|
||||
final boolean async = method.getReturnType().isAssignableFrom(CompletableFuture.class);
|
||||
Class[] paramTypes = method.getParameterTypes();
|
||||
List<AsmMethodParam> methodParams = methodBean.getParams();
|
||||
List<Integer> insns = new ArrayList<>();
|
||||
|
||||
mv = cw.visitMethod(ACC_PUBLIC, method.getName(), methodBean.getDesc(), methodBean.getSignature(), null);
|
||||
mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, method.getName(), methodBean.getDesc(), methodBean.getSignature(), null)).setDebug(false);
|
||||
Label l0 = new Label();
|
||||
mv.visitLabel(l0);
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "dataSource", "()" + sqlSourceDesc, false);
|
||||
//参数:结果类
|
||||
mv.visitLdcInsn(Type.getType(Type.getDescriptor(componentTypes[0])));
|
||||
if (resultClass.isAssignableFrom(Map.class)) {
|
||||
mv.visitLdcInsn(Type.getType(Type.getDescriptor(componentTypes[1])));
|
||||
}
|
||||
//参数:sql
|
||||
mv.visitLdcInsn(sql.value());
|
||||
mv.visitVarInsn(ASTORE, 2);
|
||||
Label l1 = new Label();
|
||||
mv.visitLabel(l1);
|
||||
mv.visitTypeInsn(NEW, "java/util/HashMap");
|
||||
mv.visitInsn(DUP);
|
||||
mv.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap", "<init>", "()V", false);
|
||||
mv.visitVarInsn(ASTORE, 3);
|
||||
//参数: params
|
||||
Asms.visitInsn(mv, paramTypes.length * 2);
|
||||
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
|
||||
int insn = 0;
|
||||
for (int i = 0; i < paramTypes.length; i++) {
|
||||
insn++;
|
||||
Class pt = paramTypes[i];
|
||||
//参数名
|
||||
mv.visitInsn(DUP);
|
||||
Asms.visitInsn(mv, i * 2);
|
||||
mv.visitLdcInsn(methodParams.get(i).getName());
|
||||
mv.visitInsn(AASTORE);
|
||||
//参数值
|
||||
mv.visitInsn(DUP);
|
||||
Asms.visitInsn(mv, i * 2 + 1);
|
||||
if (pt.isPrimitive()) {
|
||||
if (pt == long.class) {
|
||||
mv.visitVarInsn(LLOAD, insn++);
|
||||
} else if (pt == float.class) {
|
||||
mv.visitVarInsn(FLOAD, insn++);
|
||||
} else if (pt == double.class) {
|
||||
mv.visitVarInsn(DLOAD, insn++);
|
||||
} else {
|
||||
mv.visitVarInsn(ILOAD, insn);
|
||||
}
|
||||
} else {
|
||||
mv.visitVarInsn(ALOAD, insn);
|
||||
}
|
||||
insns.add(insn);
|
||||
Asms.visitPrimitiveValueOf(mv, pt);
|
||||
mv.visitInsn(AASTORE);
|
||||
}
|
||||
|
||||
mv.visitMethodInsn(INVOKESTATIC, utilClassName, "ofMap", "([Ljava/lang/Object;)Ljava/util/HashMap;", false);
|
||||
|
||||
//One: "(Ljava/lang/Class;Ljava/lang/String;Ljava/util/Map;)Ljava/lang/Object;"
|
||||
//Map: "(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;Ljava/util/Map;)Ljava/util/Map;"
|
||||
//List: "(Ljava/lang/Class;Ljava/lang/String;Ljava/util/Map;)Ljava/util/List;"
|
||||
//Sheet: "(Ljava/lang/Class;Ljava/lang/String;Lorg/redkale/source/Flipper;Ljava/util/Map;)Lorg/redkale/util/Sheet;"
|
||||
//Async: "(Ljava/lang/Class;Ljava/lang/String;Ljava/util/Map;)Ljava/util/concurrent/CompletableFuture;"
|
||||
if (sqlInfo.getSqlMode() == SELECT) {
|
||||
String queryMethodName = "nativeQueryOne";
|
||||
String queryMethodDesc = "(Ljava/lang/Class;Ljava/lang/String;Ljava/util/Map;)"
|
||||
+ (async ? "Ljava/util/concurrent/CompletableFuture;" : "Ljava/lang/Object;");
|
||||
boolean oneMode = !async;
|
||||
if (resultClass.isAssignableFrom(Map.class)) {
|
||||
oneMode = false;
|
||||
queryMethodName = "nativeQueryMap";
|
||||
queryMethodDesc = "(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;Ljava/util/Map;)"
|
||||
+ (async ? "Ljava/util/concurrent/CompletableFuture;" : "Ljava/util/Map;");
|
||||
} else if (resultClass.isAssignableFrom(List.class)) {
|
||||
oneMode = false;
|
||||
queryMethodName = "nativeQueryList";
|
||||
queryMethodDesc = "(Ljava/lang/Class;Ljava/lang/String;Ljava/util/Map;)"
|
||||
+ (async ? "Ljava/util/concurrent/CompletableFuture;" : "Ljava/util/List;");
|
||||
} else if (resultClass.isAssignableFrom(Sheet.class)) {
|
||||
oneMode = false;
|
||||
queryMethodName = "nativeQuerySheet";
|
||||
queryMethodDesc = "(Ljava/lang/Class;Ljava/lang/String;" + flipperDesc + "Ljava/util/Map;)"
|
||||
+ (async ? "Ljava/util/concurrent/CompletableFuture;" : sheetDesc);
|
||||
}
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, sqlSourceName, queryMethodName + (async ? "Async" : ""), queryMethodDesc, true);
|
||||
if (oneMode) {
|
||||
mv.visitTypeInsn(CHECKCAST, componentTypes[0].getName().replace('.', '/'));
|
||||
}
|
||||
} else {
|
||||
//UPDATE
|
||||
}
|
||||
mv.visitInsn(ARETURN);
|
||||
Label l2 = new Label();
|
||||
mv.visitLabel(l2);
|
||||
mv.visitVarInsn(ALOAD, 3);
|
||||
mv.visitLdcInsn("bean");
|
||||
mv.visitVarInsn(ALOAD, 1);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true);
|
||||
mv.visitInsn(POP);
|
||||
Label l3 = new Label();
|
||||
mv.visitLabel(l3);
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/test/source/parser/DynForumInfoMapperImpl", "dataSource", "()Lorg/redkale/source/DataSqlSource;", false);
|
||||
mv.visitLdcInsn(Type.getType("Lorg/redkale/test/source/parser/ForumResult;"));
|
||||
mv.visitVarInsn(ALOAD, 2);
|
||||
mv.visitVarInsn(ALOAD, 3);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, "org/redkale/source/DataSqlSource", "nativeQueryListAsync", "(Ljava/lang/Class;Ljava/lang/String;Ljava/util/Map;)Ljava/util/concurrent/CompletableFuture;", true);
|
||||
mv.visitInsn(ARETURN);
|
||||
Label l4 = new Label();
|
||||
mv.visitLabel(l4);
|
||||
mv.visitLocalVariable("this", "Lorg/redkale/test/source/parser/DynForumInfoMapperImpl;", null, l0, l4, 0);
|
||||
mv.visitLocalVariable("bean", "Lorg/redkale/test/source/parser/ForumBean;", null, l0, l4, 1);
|
||||
mv.visitLocalVariable("sql", "Ljava/lang/String;", null, l1, l4, 2);
|
||||
mv.visitLocalVariable("params", "Ljava/util/Map;", "Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;", l2, l4, 3);
|
||||
mv.visitMaxs(4, 4);
|
||||
mv.visitLocalVariable("this", "L" + newDynName + ";", null, l0, l2, 0);
|
||||
for (int i = 0; i < paramTypes.length; i++) {
|
||||
AsmMethodParam param = methodParams.get(i);
|
||||
mv.visitLocalVariable(param.getName(), param.description(paramTypes[i]), param.signature(paramTypes[i]), l0, l2, insns.get(i));
|
||||
}
|
||||
mv.visitMaxs(8, 5);
|
||||
mv.visitEnd();
|
||||
}
|
||||
|
||||
@@ -268,7 +358,7 @@ public final class DataSqlMapperBuilder {
|
||||
throw new SourceException("Not found entity class from " + mapperType.getName());
|
||||
}
|
||||
|
||||
private static Class returnType(Method method) {
|
||||
private static Class resultClass(Method method) {
|
||||
Class type = method.getReturnType();
|
||||
if (type.isAssignableFrom(CompletableFuture.class)) {
|
||||
ParameterizedType pt = (ParameterizedType) method.getGenericReturnType();
|
||||
@@ -277,6 +367,39 @@ public final class DataSqlMapperBuilder {
|
||||
return type;
|
||||
}
|
||||
|
||||
private static Class[] resultComponentType(Method method) {
|
||||
if (method.getReturnType().isAssignableFrom(CompletableFuture.class)) {
|
||||
ParameterizedType pt = (ParameterizedType) method.getGenericReturnType();
|
||||
return resultComponentType(pt.getActualTypeArguments()[0]);
|
||||
}
|
||||
return resultComponentType(method.getGenericReturnType());
|
||||
}
|
||||
|
||||
private static Class[] resultComponentType(java.lang.reflect.Type type) {
|
||||
Class clzz = TypeToken.typeToClass(type);
|
||||
if (clzz.isAssignableFrom(Map.class)) {
|
||||
if (type instanceof ParameterizedType) {
|
||||
java.lang.reflect.Type[] ts = ((ParameterizedType) type).getActualTypeArguments();
|
||||
return new Class[]{TypeToken.typeToClass(ts[0]), TypeToken.typeToClass(ts[1])};
|
||||
} else {
|
||||
return new Class[]{String.class, JsonObject.class};
|
||||
}
|
||||
} else if (clzz.isAssignableFrom(List.class)) {
|
||||
if (type instanceof ParameterizedType) {
|
||||
clzz = TypeToken.typeToClass(((ParameterizedType) type).getActualTypeArguments()[0]);
|
||||
} else {
|
||||
clzz = JsonObject.class;
|
||||
}
|
||||
} else if (clzz.isAssignableFrom(Sheet.class)) {
|
||||
if (type instanceof ParameterizedType) {
|
||||
clzz = TypeToken.typeToClass(((ParameterizedType) type).getActualTypeArguments()[0]);
|
||||
} else {
|
||||
clzz = JsonObject.class;
|
||||
}
|
||||
}
|
||||
return new Class[]{clzz};
|
||||
}
|
||||
|
||||
private static class Item {
|
||||
|
||||
public Method method;
|
||||
|
||||
@@ -1545,6 +1545,7 @@ public final class Utility {
|
||||
*
|
||||
* @return Map
|
||||
*/
|
||||
@AsmDepends
|
||||
public static <K, V> HashMap<K, V> ofMap(Object... items) {
|
||||
HashMap<K, V> map = new LinkedHashMap<>(Math.max(1, items.length / 2));
|
||||
int len = items.length / 2;
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
*/
|
||||
package org.redkale.test.source.parser;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.redkale.source.DataSqlMapper;
|
||||
import org.redkale.source.SourceException;
|
||||
import org.redkale.util.TypeToken;
|
||||
import org.redkale.source.DataJdbcSource;
|
||||
import org.redkale.source.DataSqlSource;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -16,24 +14,21 @@ import org.redkale.util.TypeToken;
|
||||
*/
|
||||
public class DataSqlMapperTest {
|
||||
|
||||
private static DataSqlSource source = new DataJdbcSource();
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
DataSqlMapperTest test = new DataSqlMapperTest();
|
||||
test.init();
|
||||
test.run();
|
||||
|
||||
System.out.println(entityType(ForumInfoMapper.class));
|
||||
}
|
||||
|
||||
private static Class entityType(Class mapperType) {
|
||||
for (Type t : mapperType.getGenericInterfaces()) {
|
||||
if (DataSqlMapper.class.isAssignableFrom(TypeToken.typeToClass(t))) {
|
||||
return TypeToken.typeToClass(((ParameterizedType) t).getActualTypeArguments()[0]);
|
||||
}
|
||||
}
|
||||
throw new SourceException("Not found entity class from " + mapperType.getName());
|
||||
@BeforeAll
|
||||
public static void init() throws Exception {
|
||||
//do
|
||||
}
|
||||
|
||||
@Test
|
||||
public void run() throws Exception {
|
||||
|
||||
//do
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user