DataSqlMapperBuilder
This commit is contained in:
@@ -193,7 +193,7 @@ public class MethodDebugVisitor extends MethodVisitor {
|
|||||||
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
|
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
|
||||||
visitor.visitLocalVariable(name, desc, signature, start, end, index);
|
visitor.visitLocalVariable(name, desc, signature, start, end, index);
|
||||||
if (debug) {
|
if (debug) {
|
||||||
System.out.println("mv.visitLocalVariable(\"" + name + "\", \"" + desc + "\", \"" + signature + "\", null, null, -1);");
|
System.out.println("mv.visitLocalVariable(\"" + name + "\", \"" + desc + "\", \"" + signature + "\", null, null, " + index + ");");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,26 +23,7 @@ import org.redkale.asm.FieldVisitor;
|
|||||||
import org.redkale.asm.Label;
|
import org.redkale.asm.Label;
|
||||||
import org.redkale.asm.MethodDebugVisitor;
|
import org.redkale.asm.MethodDebugVisitor;
|
||||||
import org.redkale.asm.MethodVisitor;
|
import org.redkale.asm.MethodVisitor;
|
||||||
import static org.redkale.asm.Opcodes.AASTORE;
|
import static org.redkale.asm.Opcodes.*;
|
||||||
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.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.LLOAD;
|
|
||||||
import static org.redkale.asm.Opcodes.RETURN;
|
|
||||||
import static org.redkale.asm.Opcodes.V11;
|
|
||||||
import org.redkale.asm.Type;
|
import org.redkale.asm.Type;
|
||||||
import org.redkale.convert.json.JsonObject;
|
import org.redkale.convert.json.JsonObject;
|
||||||
import org.redkale.persistence.Sql;
|
import org.redkale.persistence.Sql;
|
||||||
@@ -72,8 +53,6 @@ import org.redkale.util.Utility;
|
|||||||
*/
|
*/
|
||||||
public final class DataSqlMapperBuilder {
|
public final class DataSqlMapperBuilder {
|
||||||
|
|
||||||
private static Map<String, AsmMethodBean> baseMethodBeans;
|
|
||||||
|
|
||||||
private DataSqlMapperBuilder() {
|
private DataSqlMapperBuilder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +63,7 @@ public final class DataSqlMapperBuilder {
|
|||||||
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||||
final Class entityType = entityType(mapperType);
|
final Class entityType = entityType(mapperType);
|
||||||
final String supDynName = mapperType.getName().replace('.', '/');
|
final String supDynName = mapperType.getName().replace('.', '/');
|
||||||
final String newDynName = "org/redkaledyn/source/mapper/_DynDataSqlMapper__" + supDynName.replace('$', '_');
|
final String newDynName = "org/redkaledyn/source/mapper/_DynDataSqlMapper_" + mapperType.getName().replace('.', '_').replace('$', '_');
|
||||||
try {
|
try {
|
||||||
Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.'));
|
Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.'));
|
||||||
Class newClazz = clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz;
|
Class newClazz = clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz;
|
||||||
@@ -106,9 +85,6 @@ public final class DataSqlMapperBuilder {
|
|||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (baseMethodBeans == null) {
|
|
||||||
baseMethodBeans = AsmMethodBoost.getMethodBeans(DataSqlMapper.class);
|
|
||||||
}
|
|
||||||
List<Item> items = new ArrayList<>();
|
List<Item> items = new ArrayList<>();
|
||||||
Map<String, AsmMethodBean> selfMethodBeans = AsmMethodBoost.getMethodBeans(mapperType);
|
Map<String, AsmMethodBean> selfMethodBeans = AsmMethodBoost.getMethodBeans(mapperType);
|
||||||
for (Method method : mapperType.getMethods()) {
|
for (Method method : mapperType.getMethods()) {
|
||||||
@@ -124,12 +100,14 @@ public final class DataSqlMapperBuilder {
|
|||||||
Sql sql = method.getAnnotation(Sql.class);
|
Sql sql = method.getAnnotation(Sql.class);
|
||||||
if (sql == null) {
|
if (sql == null) {
|
||||||
if (Modifier.isAbstract(method.getModifiers())) {
|
if (Modifier.isAbstract(method.getModifiers())) {
|
||||||
throw new SourceException(method + " require @" + Sql.class.getSimpleName());
|
throw new SourceException(mapperType.getSimpleName()
|
||||||
|
+ "." + method.getName() + " require @" + Sql.class.getSimpleName());
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!Modifier.isAbstract(method.getModifiers())) {
|
if (!Modifier.isAbstract(method.getModifiers())) {
|
||||||
throw new SourceException(method + " is not abstract, but contains @" + Sql.class.getSimpleName());
|
throw new SourceException(mapperType.getSimpleName() + "." + method.getName()
|
||||||
|
+ " is not abstract, but contains @" + Sql.class.getSimpleName());
|
||||||
}
|
}
|
||||||
if (method.getExceptionTypes().length > 0) {
|
if (method.getExceptionTypes().length > 0) {
|
||||||
throw new SourceException("@" + Sql.class.getSimpleName() + " cannot on throw-exception method, but " + method);
|
throw new SourceException("@" + Sql.class.getSimpleName() + " cannot on throw-exception method, but " + method);
|
||||||
@@ -140,18 +118,33 @@ public final class DataSqlMapperBuilder {
|
|||||||
}
|
}
|
||||||
DataNativeSqlInfo sqlInfo = nativeSqlParser.parse(signFunc, source.getType(), sql.value());
|
DataNativeSqlInfo sqlInfo = nativeSqlParser.parse(signFunc, source.getType(), sql.value());
|
||||||
AsmMethodBean methodBean = selfMethodBeans.get(AsmMethodBoost.getMethodBeanKey(method));
|
AsmMethodBean methodBean = selfMethodBeans.get(AsmMethodBoost.getMethodBeanKey(method));
|
||||||
if (!Utility.equalsElement(sqlInfo.getRootParamNames(), methodBean.fieldNameList())) {
|
List<String> fieldNames = methodBean.fieldNameList();
|
||||||
throw new SourceException(method + " parameters not match @" + Sql.class.getSimpleName() + "(" + sql.value() + ")");
|
|
||||||
}
|
|
||||||
Class resultClass = resultClass(method);
|
Class resultClass = resultClass(method);
|
||||||
|
int flipperIndex = -1;
|
||||||
|
if (resultClass.isAssignableFrom(Sheet.class)) {
|
||||||
|
Class[] pts = method.getParameterTypes();
|
||||||
|
for (int i = 0; i < pts.length; i++) {
|
||||||
|
if (pts[i] == Flipper.class) {
|
||||||
|
flipperIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flipperIndex < 0) {
|
||||||
|
throw new SourceException(mapperType.getSimpleName() + "." + method.getName()
|
||||||
|
+ " need Flipper type parameter on @" + Sql.class.getSimpleName() + "(" + sql.value() + ")");
|
||||||
|
}
|
||||||
|
fieldNames.remove(flipperIndex);
|
||||||
|
}
|
||||||
|
if (!Utility.equalsElement(sqlInfo.getRootParamNames(), fieldNames)) {
|
||||||
|
throw new SourceException(mapperType.getSimpleName() + "." + method.getName()
|
||||||
|
+ " parameters not match, fieldNames = " + fieldNames + ", sqlParams = " + sqlInfo.getRootParamNames() + ", methodBean = " + methodBean);
|
||||||
|
}
|
||||||
if (sqlInfo.getSqlMode() != SELECT) { //非SELECT语句只能返回int或void
|
if (sqlInfo.getSqlMode() != SELECT) { //非SELECT语句只能返回int或void
|
||||||
if (resultClass != Integer.class && resultClass != int.class
|
if (resultClass != Integer.class && resultClass != int.class) {
|
||||||
&& resultClass != Void.class && resultClass != void.class) {
|
throw new SourceException("Update SQL must on return int method, but " + method);
|
||||||
throw new SourceException("@" + Sql.class.getSimpleName()
|
|
||||||
+ "(" + sql.value() + ") must on return int or void method, but " + method);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
items.add(new Item(method, sqlInfo, methodBean));
|
items.add(new Item(method, sqlInfo, methodBean, flipperIndex));
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -220,6 +213,7 @@ public final class DataSqlMapperBuilder {
|
|||||||
Method method = item.method;
|
Method method = item.method;
|
||||||
DataNativeSqlInfo sqlInfo = item.sqlInfo;
|
DataNativeSqlInfo sqlInfo = item.sqlInfo;
|
||||||
AsmMethodBean methodBean = item.methodBean;
|
AsmMethodBean methodBean = item.methodBean;
|
||||||
|
int flipperIndex = item.flipperIndex;
|
||||||
Sql sql = method.getAnnotation(Sql.class);
|
Sql sql = method.getAnnotation(Sql.class);
|
||||||
Class resultClass = resultClass(method);
|
Class resultClass = resultClass(method);
|
||||||
Class[] componentTypes = resultComponentType(method);
|
Class[] componentTypes = resultComponentType(method);
|
||||||
@@ -233,44 +227,51 @@ public final class DataSqlMapperBuilder {
|
|||||||
mv.visitLabel(l0);
|
mv.visitLabel(l0);
|
||||||
mv.visitVarInsn(ALOAD, 0);
|
mv.visitVarInsn(ALOAD, 0);
|
||||||
mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "dataSource", "()" + sqlSourceDesc, false);
|
mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "dataSource", "()" + sqlSourceDesc, false);
|
||||||
//参数:结果类
|
if (sqlInfo.getSqlMode() == SELECT) {
|
||||||
mv.visitLdcInsn(Type.getType(Type.getDescriptor(componentTypes[0])));
|
//参数:结果类
|
||||||
if (resultClass.isAssignableFrom(Map.class)) {
|
mv.visitLdcInsn(Type.getType(Type.getDescriptor(componentTypes[0])));
|
||||||
mv.visitLdcInsn(Type.getType(Type.getDescriptor(componentTypes[1])));
|
if (resultClass.isAssignableFrom(Map.class)) {
|
||||||
|
mv.visitLdcInsn(Type.getType(Type.getDescriptor(componentTypes[1])));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//参数:sql
|
//参数:sql
|
||||||
mv.visitLdcInsn(sql.value());
|
mv.visitLdcInsn(sql.value());
|
||||||
|
if (flipperIndex >= 0) {
|
||||||
|
mv.visitVarInsn(ALOAD, flipperIndex + 1);
|
||||||
|
}
|
||||||
//参数: params
|
//参数: params
|
||||||
Asms.visitInsn(mv, paramTypes.length * 2);
|
Asms.visitInsn(mv, paramTypes.length * 2 - (flipperIndex >= 0 ? 2 : 0));
|
||||||
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
|
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
|
||||||
int insn = 0;
|
int insn = 0;
|
||||||
for (int i = 0; i < paramTypes.length; i++) {
|
for (int i = 0; i < paramTypes.length; i++) {
|
||||||
insn++;
|
insn++;
|
||||||
Class pt = paramTypes[i];
|
if (i != flipperIndex) {
|
||||||
//参数名
|
Class pt = paramTypes[i];
|
||||||
mv.visitInsn(DUP);
|
//参数名
|
||||||
Asms.visitInsn(mv, i * 2);
|
mv.visitInsn(DUP);
|
||||||
mv.visitLdcInsn(methodParams.get(i).getName());
|
Asms.visitInsn(mv, i * 2);
|
||||||
mv.visitInsn(AASTORE);
|
mv.visitLdcInsn(methodParams.get(i).getName());
|
||||||
//参数值
|
mv.visitInsn(AASTORE);
|
||||||
mv.visitInsn(DUP);
|
//参数值
|
||||||
Asms.visitInsn(mv, i * 2 + 1);
|
mv.visitInsn(DUP);
|
||||||
if (pt.isPrimitive()) {
|
Asms.visitInsn(mv, i * 2 + 1);
|
||||||
if (pt == long.class) {
|
if (pt.isPrimitive()) {
|
||||||
mv.visitVarInsn(LLOAD, insn++);
|
if (pt == long.class) {
|
||||||
} else if (pt == float.class) {
|
mv.visitVarInsn(LLOAD, insn++);
|
||||||
mv.visitVarInsn(FLOAD, insn++);
|
} else if (pt == float.class) {
|
||||||
} else if (pt == double.class) {
|
mv.visitVarInsn(FLOAD, insn++);
|
||||||
mv.visitVarInsn(DLOAD, insn++);
|
} else if (pt == double.class) {
|
||||||
|
mv.visitVarInsn(DLOAD, insn++);
|
||||||
|
} else {
|
||||||
|
mv.visitVarInsn(ILOAD, insn);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mv.visitVarInsn(ILOAD, insn);
|
mv.visitVarInsn(ALOAD, insn);
|
||||||
}
|
}
|
||||||
} else {
|
Asms.visitPrimitiveValueOf(mv, pt);
|
||||||
mv.visitVarInsn(ALOAD, insn);
|
mv.visitInsn(AASTORE);
|
||||||
}
|
}
|
||||||
insns.add(insn);
|
insns.add(insn);
|
||||||
Asms.visitPrimitiveValueOf(mv, pt);
|
|
||||||
mv.visitInsn(AASTORE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mv.visitMethodInsn(INVOKESTATIC, utilClassName, "ofMap", "([Ljava/lang/Object;)Ljava/util/HashMap;", false);
|
mv.visitMethodInsn(INVOKESTATIC, utilClassName, "ofMap", "([Ljava/lang/Object;)Ljava/util/HashMap;", false);
|
||||||
@@ -305,10 +306,23 @@ public final class DataSqlMapperBuilder {
|
|||||||
if (oneMode) {
|
if (oneMode) {
|
||||||
mv.visitTypeInsn(CHECKCAST, componentTypes[0].getName().replace('.', '/'));
|
mv.visitTypeInsn(CHECKCAST, componentTypes[0].getName().replace('.', '/'));
|
||||||
}
|
}
|
||||||
|
mv.visitInsn(ARETURN);
|
||||||
} else {
|
} else {
|
||||||
//UPDATE
|
String updateMethodName = "nativeUpdate" + (async ? "Async" : "");
|
||||||
|
String updateMethodDesc = "(Ljava/lang/String;Ljava/util/Map;)" + (async ? "Ljava/util/concurrent/CompletableFuture;" : "I");
|
||||||
|
mv.visitMethodInsn(INVOKEINTERFACE, sqlSourceName, updateMethodName, updateMethodDesc, true);
|
||||||
|
if (resultClass == int.class) {
|
||||||
|
mv.visitInsn(IRETURN);
|
||||||
|
} else if (!async && resultClass == Integer.class) {
|
||||||
|
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
|
||||||
|
mv.visitInsn(ARETURN);
|
||||||
|
} else if (resultClass == void.class) {
|
||||||
|
mv.visitInsn(POP);
|
||||||
|
mv.visitInsn(RETURN);
|
||||||
|
} else {
|
||||||
|
mv.visitInsn(ARETURN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mv.visitInsn(ARETURN);
|
|
||||||
Label l2 = new Label();
|
Label l2 = new Label();
|
||||||
mv.visitLabel(l2);
|
mv.visitLabel(l2);
|
||||||
mv.visitLocalVariable("this", "L" + newDynName + ";", null, l0, l2, 0);
|
mv.visitLocalVariable("this", "L" + newDynName + ";", null, l0, l2, 0);
|
||||||
@@ -408,10 +422,13 @@ public final class DataSqlMapperBuilder {
|
|||||||
|
|
||||||
public AsmMethodBean methodBean;
|
public AsmMethodBean methodBean;
|
||||||
|
|
||||||
public Item(Method method, DataNativeSqlInfo sqlInfo, AsmMethodBean methodBean) {
|
public int flipperIndex = -1;
|
||||||
|
|
||||||
|
public Item(Method method, DataNativeSqlInfo sqlInfo, AsmMethodBean methodBean, int flipperIndex) {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.sqlInfo = sqlInfo;
|
this.sqlInfo = sqlInfo;
|
||||||
this.methodBean = methodBean;
|
this.methodBean = methodBean;
|
||||||
|
this.flipperIndex = flipperIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -516,14 +516,14 @@ public class SourceModuleEngine extends ModuleEngine implements SourceManager {
|
|||||||
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) {
|
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) {
|
||||||
return null; //远程模式不得注入
|
return null; //远程模式不得注入
|
||||||
}
|
}
|
||||||
DataSqlMapper old = resourceFactory.find(resourceName, DataSqlMapper.class);
|
Class<? extends DataSqlMapper> mapperType = (Class) field.getType();
|
||||||
|
DataSqlMapper old = resourceFactory.find(resourceName, mapperType);
|
||||||
if (old != null) {
|
if (old != null) {
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
DataSource source = loadDataSource(resourceName, false);
|
DataSource source = loadDataSource(resourceName, false);
|
||||||
Class mapperType = field.getType();
|
|
||||||
DataSqlMapper mapper = DataSqlMapperBuilder.createMapper(nativeSqlParser, (DataSqlSource) source, mapperType);
|
DataSqlMapper mapper = DataSqlMapperBuilder.createMapper(nativeSqlParser, (DataSqlSource) source, mapperType);
|
||||||
resourceFactory.register(resourceName, DataSqlMapper.class, mapper);
|
resourceFactory.register(resourceName, mapperType, mapper);
|
||||||
field.set(srcObj, mapper);
|
field.set(srcObj, mapper);
|
||||||
return mapper;
|
return mapper;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
Reference in New Issue
Block a user