EntityFullFunc
This commit is contained in:
@@ -3,11 +3,10 @@
|
||||
*/
|
||||
package org.redkale.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.*;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 被标记的元素表示会被动态字节码调用
|
||||
*
|
||||
@@ -17,7 +16,7 @@ import java.lang.annotation.*;
|
||||
* @since 2.8.0
|
||||
*/
|
||||
@Documented
|
||||
@Target({TYPE, METHOD, FIELD})
|
||||
@Target({TYPE, METHOD, FIELD, CONSTRUCTOR})
|
||||
@Retention(SOURCE)
|
||||
public @interface ClassDepends {
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ public class EntityBuilder<T> {
|
||||
sqlLowerAttrMap.put(lowerCaseColumn(col), v);
|
||||
});
|
||||
if (constructorAttributes == null && !entityIsMap) {
|
||||
this.fullFunc = EntityFullFunc.create(type, creator, unconstructorAttributes);
|
||||
this.fullFunc = EntityFullFunc.create(type, creator, attributes);
|
||||
} else {
|
||||
this.fullFunc = null;
|
||||
}
|
||||
@@ -576,6 +576,10 @@ public class EntityBuilder<T> {
|
||||
return constructorAttributes != null;
|
||||
}
|
||||
|
||||
public EntityFullFunc<T> getFullFunc() {
|
||||
return fullFunc;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断Entity类的字段名与表字段名s是否存在不一致的值
|
||||
*
|
||||
|
||||
@@ -5,8 +5,44 @@
|
||||
package org.redkale.source;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
import org.redkale.annotation.ClassDepends;
|
||||
import org.redkale.asm.AnnotationVisitor;
|
||||
import org.redkale.asm.Asms;
|
||||
import org.redkale.asm.ClassWriter;
|
||||
import org.redkale.asm.FieldVisitor;
|
||||
import org.redkale.asm.Label;
|
||||
import org.redkale.asm.MethodVisitor;
|
||||
import org.redkale.asm.Opcodes;
|
||||
import static org.redkale.asm.Opcodes.ACC_BRIDGE;
|
||||
import static org.redkale.asm.Opcodes.ACC_FINAL;
|
||||
import static org.redkale.asm.Opcodes.ACC_PUBLIC;
|
||||
import static org.redkale.asm.Opcodes.ACC_SUPER;
|
||||
import static org.redkale.asm.Opcodes.ACC_SYNTHETIC;
|
||||
import static org.redkale.asm.Opcodes.ACONST_NULL;
|
||||
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.DCONST_0;
|
||||
import static org.redkale.asm.Opcodes.FCONST_0;
|
||||
import static org.redkale.asm.Opcodes.GETFIELD;
|
||||
import static org.redkale.asm.Opcodes.ICONST_0;
|
||||
import static org.redkale.asm.Opcodes.IFEQ;
|
||||
import static org.redkale.asm.Opcodes.INVOKEINTERFACE;
|
||||
import static org.redkale.asm.Opcodes.INVOKESPECIAL;
|
||||
import static org.redkale.asm.Opcodes.INVOKEVIRTUAL;
|
||||
import static org.redkale.asm.Opcodes.LCONST_0;
|
||||
import static org.redkale.asm.Opcodes.PUTFIELD;
|
||||
import static org.redkale.asm.Opcodes.RETURN;
|
||||
import static org.redkale.asm.Opcodes.V11;
|
||||
import org.redkale.asm.Type;
|
||||
import org.redkale.util.Attribute;
|
||||
import org.redkale.util.Creator;
|
||||
import org.redkale.util.RedkaleClassLoader;
|
||||
import org.redkale.util.RedkaleException;
|
||||
import org.redkale.util.Utility;
|
||||
|
||||
/**
|
||||
* 可以是实体类,也可以是查询结果的JavaBean类
|
||||
@@ -23,14 +59,16 @@ public abstract class EntityFullFunc<T> {
|
||||
|
||||
protected final Attribute<T, Serializable>[] attrs;
|
||||
|
||||
@ClassDepends
|
||||
protected EntityFullFunc(Class<T> type, Creator<T> creator, Attribute<T, Serializable>[] attrs) {
|
||||
this.type = type;
|
||||
this.creator = creator;
|
||||
this.attrs = attrs;
|
||||
this.type = Objects.requireNonNull(type);
|
||||
this.creator = Objects.requireNonNull(creator);
|
||||
this.attrs = Objects.requireNonNull(attrs);
|
||||
}
|
||||
|
||||
public abstract T getObject(DataResultSetRow row);
|
||||
|
||||
@ClassDepends
|
||||
protected void setFieldValue(int attrIndex, DataResultSetRow row, T obj) {
|
||||
Attribute<T, Serializable> attr = attrs[attrIndex];
|
||||
if (attr != null) {
|
||||
@@ -50,7 +88,379 @@ public abstract class EntityFullFunc<T> {
|
||||
return attrs;
|
||||
}
|
||||
|
||||
public static <T> EntityFullFunc<T> create(Class<T> type, Creator<T> creator, Attribute<T, Serializable>[] attrs) {
|
||||
return null;
|
||||
static <T> EntityFullFunc<T> create(Class<T> entityType, Creator<T> creator, Attribute<T, Serializable>[] attrs) {
|
||||
final String supDynName = EntityFullFunc.class.getName().replace('.', '/');
|
||||
final String entityName = entityType.getName().replace('.', '/');
|
||||
final String entityDesc = Type.getDescriptor(entityType);
|
||||
final String creatorDesc = Type.getDescriptor(Creator.class);
|
||||
final String creatorName = Creator.class.getName().replace('.', '/');
|
||||
final String attrDesc = Type.getDescriptor(Attribute.class);
|
||||
final String attrName = Attribute.class.getName().replace('.', '/');
|
||||
final String rowDesc = Type.getDescriptor(DataResultSetRow.class);
|
||||
final String rowName = DataResultSetRow.class.getName().replace('.', '/');
|
||||
final String objectDesc = Type.getDescriptor(Object.class);
|
||||
|
||||
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||
if (String.class.getClassLoader() != entityType.getClassLoader()) {
|
||||
loader = entityType.getClassLoader();
|
||||
}
|
||||
final String newDynName = "org/redkaledyn/source/_Dyn" + EntityFullFunc.class.getSimpleName() + "__"
|
||||
+ entityType.getName().replace('.', '_').replace('$', '_');
|
||||
try {
|
||||
Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.'));
|
||||
return (EntityFullFunc) (clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz)
|
||||
.getConstructor(Class.class, Creator.class, Attribute[].class)
|
||||
.newInstance(entityType, creator, attrs);
|
||||
} catch (Throwable ex) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
||||
FieldVisitor fv;
|
||||
MethodVisitor mv;
|
||||
AnnotationVisitor av0;
|
||||
cw.visit(
|
||||
V11,
|
||||
ACC_PUBLIC + ACC_FINAL + ACC_SUPER,
|
||||
newDynName,
|
||||
"L" + supDynName + "<" + entityDesc + ">;",
|
||||
supDynName,
|
||||
null);
|
||||
|
||||
{ // 构造方法
|
||||
mv = cw.visitMethod(
|
||||
ACC_PUBLIC,
|
||||
"<init>",
|
||||
"(Ljava/lang/Class;" + creatorDesc + "[" + attrDesc + ")V",
|
||||
"(Ljava/lang/Class<" + entityDesc + ">;L" + creatorName + "<" + entityDesc + ">;[L" + attrName + "<"
|
||||
+ entityDesc + "Ljava/io/Serializable;>;)V",
|
||||
null);
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitVarInsn(ALOAD, 1);
|
||||
mv.visitVarInsn(ALOAD, 2);
|
||||
mv.visitVarInsn(ALOAD, 3);
|
||||
mv.visitMethodInsn(
|
||||
INVOKESPECIAL,
|
||||
supDynName,
|
||||
"<init>",
|
||||
"(Ljava/lang/Class;" + creatorDesc + "[" + attrDesc + ")V",
|
||||
false);
|
||||
mv.visitInsn(RETURN);
|
||||
mv.visitMaxs(4, 4);
|
||||
mv.visitEnd();
|
||||
}
|
||||
{ // getObject
|
||||
mv = cw.visitMethod(ACC_PUBLIC, "getObject", "(" + rowDesc + ")" + entityDesc, null, null);
|
||||
mv.visitVarInsn(ALOAD, 1);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "wasNull", "()Z", true);
|
||||
Label ifLabel = new Label();
|
||||
mv.visitJumpInsn(IFEQ, ifLabel);
|
||||
mv.visitInsn(ACONST_NULL);
|
||||
mv.visitInsn(ARETURN);
|
||||
mv.visitLabel(ifLabel);
|
||||
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
|
||||
// creator.create()
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitFieldInsn(GETFIELD, supDynName, "creator", creatorDesc);
|
||||
mv.visitInsn(ICONST_0);
|
||||
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, creatorName, "create", "([Ljava/lang/Object;)Ljava/lang/Object;", true);
|
||||
mv.visitTypeInsn(CHECKCAST, entityName);
|
||||
mv.visitVarInsn(ASTORE, 2);
|
||||
|
||||
for (int i = 0; i < attrs.length; i++) {
|
||||
final int attrIndex = i;
|
||||
final Attribute<T, Serializable> attr = attrs[i];
|
||||
java.lang.reflect.Method setter = null;
|
||||
java.lang.reflect.Field field = null;
|
||||
try {
|
||||
setter = entityType.getMethod("set" + Utility.firstCharUpperCase(attr.field()), attr.type());
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
field = entityType.getField(attr.field());
|
||||
} catch (Exception e2) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
if (attr.type() == boolean.class) {
|
||||
if (setter != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitInsn(ICONST_0);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getBoolean", "(IZ)Z", true);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, entityName, setter.getName(), "(Z)V", false);
|
||||
continue;
|
||||
} else if (field != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitInsn(ICONST_0);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getBoolean", "(IZ)Z", true);
|
||||
mv.visitFieldInsn(PUTFIELD, entityName, field.getName(), "Z");
|
||||
continue;
|
||||
}
|
||||
} else if (attr.type() == short.class) {
|
||||
if (setter != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitInsn(ICONST_0);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getShort", "(IS)S", true);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, entityName, setter.getName(), "(S)V", false);
|
||||
continue;
|
||||
} else if (field != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitInsn(ICONST_0);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getShort", "(IS)S", true);
|
||||
mv.visitFieldInsn(PUTFIELD, entityName, field.getName(), "S");
|
||||
continue;
|
||||
}
|
||||
} else if (attr.type() == int.class) {
|
||||
if (setter != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitInsn(ICONST_0);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getInteger", "(II)I", true);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, entityName, setter.getName(), "(I)V", false);
|
||||
continue;
|
||||
} else if (field != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitInsn(ICONST_0);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getInteger", "(II)I", true);
|
||||
mv.visitFieldInsn(PUTFIELD, entityName, field.getName(), "I");
|
||||
continue;
|
||||
}
|
||||
} else if (attr.type() == float.class) {
|
||||
if (setter != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitInsn(FCONST_0);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getFloat", "(IF)F", true);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, entityName, setter.getName(), "(F)V", false);
|
||||
continue;
|
||||
} else if (field != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitInsn(FCONST_0);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getFloat", "(IF)F", true);
|
||||
mv.visitFieldInsn(PUTFIELD, entityName, field.getName(), "F");
|
||||
continue;
|
||||
}
|
||||
} else if (attr.type() == long.class) {
|
||||
if (setter != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitInsn(LCONST_0);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getLong", "(IJ)J", true);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, entityName, setter.getName(), "(J)V", false);
|
||||
continue;
|
||||
} else if (field != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitInsn(LCONST_0);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getLong", "(IJ)J", true);
|
||||
mv.visitFieldInsn(PUTFIELD, entityName, field.getName(), "J");
|
||||
continue;
|
||||
}
|
||||
} else if (attr.type() == double.class) {
|
||||
if (setter != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitInsn(DCONST_0);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getDouble", "(ID)D", true);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, entityName, setter.getName(), "(D)V", false);
|
||||
continue;
|
||||
} else if (field != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitInsn(DCONST_0);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getDouble", "(ID)D", true);
|
||||
mv.visitFieldInsn(PUTFIELD, entityName, field.getName(), "D");
|
||||
continue;
|
||||
}
|
||||
} else if (attr.type() == Boolean.class) {
|
||||
if (setter != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getBoolean", "(I)Ljava/lang/Boolean;", true);
|
||||
mv.visitMethodInsn(
|
||||
INVOKEVIRTUAL, entityName, setter.getName(), "(Ljava/lang/Boolean;)V", false);
|
||||
continue;
|
||||
} else if (field != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getBoolean", "(I)Ljava/lang/Boolean;", true);
|
||||
mv.visitFieldInsn(PUTFIELD, entityName, field.getName(), "Ljava/lang/Boolean;");
|
||||
continue;
|
||||
}
|
||||
} else if (attr.type() == Short.class) {
|
||||
if (setter != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getShort", "(I)Ljava/lang/Short;", true);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, entityName, setter.getName(), "(Ljava/lang/Short;)V", false);
|
||||
continue;
|
||||
} else if (field != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getShort", "(I)Ljava/lang/Short;", true);
|
||||
mv.visitFieldInsn(PUTFIELD, entityName, field.getName(), "Ljava/lang/Short;");
|
||||
continue;
|
||||
}
|
||||
} else if (attr.type() == Integer.class) {
|
||||
if (setter != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getInteger", "(I)Ljava/lang/Integer;", true);
|
||||
mv.visitMethodInsn(
|
||||
INVOKEVIRTUAL, entityName, setter.getName(), "(Ljava/lang/Integer;)V", false);
|
||||
continue;
|
||||
} else if (field != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getInteger", "(I)Ljava/lang/Integer;", true);
|
||||
mv.visitFieldInsn(PUTFIELD, entityName, field.getName(), "Ljava/lang/Integer;");
|
||||
continue;
|
||||
}
|
||||
} else if (attr.type() == Float.class) {
|
||||
if (setter != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getFloat", "(I)Ljava/lang/Float;", true);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, entityName, setter.getName(), "(Ljava/lang/Float;)V", false);
|
||||
continue;
|
||||
} else if (field != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getFloat", "(I)Ljava/lang/Float;", true);
|
||||
mv.visitFieldInsn(PUTFIELD, entityName, field.getName(), "Ljava/lang/Float;");
|
||||
continue;
|
||||
}
|
||||
} else if (attr.type() == Long.class) {
|
||||
if (setter != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getLong", "(I)Ljava/lang/Long;", true);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, entityName, setter.getName(), "(Ljava/lang/Long;)V", false);
|
||||
continue;
|
||||
} else if (field != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getLong", "(I)Ljava/lang/Long;", true);
|
||||
mv.visitFieldInsn(PUTFIELD, entityName, field.getName(), "Ljava/lang/Long;");
|
||||
continue;
|
||||
}
|
||||
} else if (attr.type() == Double.class) {
|
||||
if (setter != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getDouble", "(I)Ljava/lang/Double;", true);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, entityName, setter.getName(), "(Ljava/lang/Double;)V", false);
|
||||
continue;
|
||||
} else if (field != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getDouble", "(I)Ljava/lang/Double;", true);
|
||||
mv.visitFieldInsn(PUTFIELD, entityName, field.getName(), "Ljava/lang/Double;");
|
||||
continue;
|
||||
}
|
||||
} else if (attr.type() == String.class) {
|
||||
if (setter != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getString", "(I)Ljava/lang/String;", true);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, entityName, setter.getName(), "(Ljava/lang/String;)V", false);
|
||||
continue;
|
||||
} else if (field != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getString", "(I)Ljava/lang/String;", true);
|
||||
mv.visitFieldInsn(PUTFIELD, entityName, field.getName(), "Ljava/lang/String;");
|
||||
continue;
|
||||
}
|
||||
} else if (attr.type() == byte[].class) {
|
||||
if (setter != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getBytes", "(I)[B", true);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, entityName, setter.getName(), "([B)V", false);
|
||||
continue;
|
||||
} else if (field != null) {
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, rowName, "getBytes", "(I)[B", true);
|
||||
mv.visitFieldInsn(PUTFIELD, entityName, field.getName(), "[B");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
Asms.visitInsn(mv, attrIndex);
|
||||
mv.visitVarInsn(ALOAD, 1); // row
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitMethodInsn(
|
||||
INVOKEVIRTUAL, supDynName, "setFieldValue", "(I" + rowDesc + objectDesc + ")V", false);
|
||||
}
|
||||
|
||||
mv.visitVarInsn(ALOAD, 2); // obj
|
||||
mv.visitInsn(ARETURN);
|
||||
mv.visitMaxs(5, 3);
|
||||
mv.visitEnd();
|
||||
}
|
||||
{ // 虚拟 getObject 方法
|
||||
mv = cw.visitMethod(
|
||||
ACC_PUBLIC | ACC_BRIDGE | ACC_SYNTHETIC, "getObject", "(" + rowDesc + ")" + objectDesc, null, null);
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitVarInsn(ALOAD, 1);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "getObject", "(" + rowDesc + ")" + entityDesc, false);
|
||||
mv.visitInsn(ARETURN);
|
||||
mv.visitMaxs(2, 2);
|
||||
mv.visitEnd();
|
||||
}
|
||||
cw.visitEnd();
|
||||
|
||||
byte[] bytes = cw.toByteArray();
|
||||
Class<EntityFullFunc> newClazz = (Class<EntityFullFunc>)
|
||||
new ClassLoader(loader) {
|
||||
public final Class<?> loadClass(String name, byte[] b) {
|
||||
return defineClass(name, b, 0, b.length);
|
||||
}
|
||||
}.loadClass(newDynName.replace('/', '.'), bytes);
|
||||
RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, newClazz);
|
||||
RedkaleClassLoader.putReflectionDeclaredConstructors(newClazz, newDynName.replace('/', '.'));
|
||||
try {
|
||||
return newClazz.getConstructor(Class.class, Creator.class, Attribute[].class)
|
||||
.newInstance(entityType, creator, attrs);
|
||||
} catch (Exception ex) {
|
||||
throw new RedkaleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
151
src/test/java/org/redkale/test/source/EntityFullFuncTest.java
Normal file
151
src/test/java/org/redkale/test/source/EntityFullFuncTest.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2116 Redkale
|
||||
* All rights reserved.
|
||||
*/
|
||||
package org.redkale.test.source;
|
||||
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.redkale.source.DataResultSetRow;
|
||||
import org.redkale.source.EntityBuilder;
|
||||
import org.redkale.source.EntityFullFunc;
|
||||
import org.redkale.source.EntityInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public class EntityFullFuncTest {
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
EntityFullFuncTest test = new EntityFullFuncTest();
|
||||
test.run1();
|
||||
test.run2();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void run1() throws Exception {
|
||||
EntityFullFunc<FullBean> func = EntityBuilder.load(FullBean.class).getFullFunc();
|
||||
Assertions.assertTrue(func != null);
|
||||
FullBean bean = func.getObject(fullBeanRow);
|
||||
System.out.println(bean);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void run2() throws Exception {
|
||||
EntityFullFunc<FullBean2> func2 = EntityBuilder.load(FullBean2.class).getFullFunc();
|
||||
Assertions.assertTrue(func2 != null);
|
||||
EntityFullFunc<FullBean> func = EntityBuilder.load(FullBean.class).getFullFunc();
|
||||
FullBean bean = func.getObject(fullBeanRow);
|
||||
FullBean2 bean2 = func2.getObject(fullBeanRow);
|
||||
Assertions.assertEquals(bean.toString(), bean2.toString());
|
||||
}
|
||||
|
||||
protected static final DataResultSetRow fullBeanRow = new DataResultSetRow() {
|
||||
@Override
|
||||
public EntityInfo getEntityInfo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObject(int columnIdex) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObject(String columnLabel) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(int columnIdex) {
|
||||
return "mystring";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(String columnLabel) {
|
||||
return "mystring";
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes(int columnIdex) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes(String columnLabel) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getBoolean(int columnIdex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getBoolean(String columnLabel) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Short getShort(int columnIdex) {
|
||||
return 111;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Short getShort(String columnLabel) {
|
||||
return 111;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getInteger(int columnIdex) {
|
||||
return 222;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getInteger(String columnLabel) {
|
||||
return 222;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float getFloat(int columnIdex) {
|
||||
return 333.f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float getFloat(String columnLabel) {
|
||||
return 333.f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getLong(int columnIdex) {
|
||||
return 444L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getLong(String columnLabel) {
|
||||
return 444L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getDouble(int columnIdex) {
|
||||
return 555.d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getDouble(String columnLabel) {
|
||||
return 555.d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasNull() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getColumnLabels() {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
};
|
||||
}
|
||||
53
src/test/java/org/redkale/test/source/FullBean2.java
Normal file
53
src/test/java/org/redkale/test/source/FullBean2.java
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2116 Redkale
|
||||
* All rights reserved.
|
||||
*/
|
||||
package org.redkale.test.source;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import org.redkale.convert.json.JsonConvert;
|
||||
import org.redkale.persistence.Id;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public class FullBean2 {
|
||||
@Id
|
||||
public long seqid;
|
||||
|
||||
public String name;
|
||||
|
||||
public byte[] img;
|
||||
|
||||
public BigInteger number;
|
||||
|
||||
public boolean flag;
|
||||
|
||||
public short status;
|
||||
|
||||
public int id;
|
||||
|
||||
public long createTime;
|
||||
|
||||
public float point;
|
||||
|
||||
public double money;
|
||||
|
||||
public Boolean flag2;
|
||||
|
||||
public Short status2;
|
||||
|
||||
public Integer id2;
|
||||
|
||||
public Long createTime2;
|
||||
|
||||
public Float point2;
|
||||
|
||||
public Double money2;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return JsonConvert.root().convertTo(this);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user