From a060075d08f8716901420ab46a4446df3a8b753d Mon Sep 17 00:00:00 2001 From: redkale Date: Sun, 22 Sep 2024 23:38:39 +0800 Subject: [PATCH] EntityFullFunc --- .../org/redkale/annotation/ClassDepends.java | 5 +- .../org/redkale/source/EntityBuilder.java | 6 +- .../org/redkale/source/EntityFullFunc.java | 420 +++++++++++++++++- .../test/source/EntityFullFuncTest.java | 151 +++++++ .../org/redkale/test/source/FullBean2.java | 53 +++ 5 files changed, 626 insertions(+), 9 deletions(-) create mode 100644 src/test/java/org/redkale/test/source/EntityFullFuncTest.java create mode 100644 src/test/java/org/redkale/test/source/FullBean2.java diff --git a/src/main/java/org/redkale/annotation/ClassDepends.java b/src/main/java/org/redkale/annotation/ClassDepends.java index 0ef4a58c7..ab6d2d547 100644 --- a/src/main/java/org/redkale/annotation/ClassDepends.java +++ b/src/main/java/org/redkale/annotation/ClassDepends.java @@ -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 { diff --git a/src/main/java/org/redkale/source/EntityBuilder.java b/src/main/java/org/redkale/source/EntityBuilder.java index f92e82dba..cfd9c2bb0 100644 --- a/src/main/java/org/redkale/source/EntityBuilder.java +++ b/src/main/java/org/redkale/source/EntityBuilder.java @@ -96,7 +96,7 @@ public class EntityBuilder { 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 { return constructorAttributes != null; } + public EntityFullFunc getFullFunc() { + return fullFunc; + } + /** * 判断Entity类的字段名与表字段名s是否存在不一致的值 * diff --git a/src/main/java/org/redkale/source/EntityFullFunc.java b/src/main/java/org/redkale/source/EntityFullFunc.java index be135ebd6..1add975a5 100644 --- a/src/main/java/org/redkale/source/EntityFullFunc.java +++ b/src/main/java/org/redkale/source/EntityFullFunc.java @@ -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 { protected final Attribute[] attrs; + @ClassDepends protected EntityFullFunc(Class type, Creator creator, Attribute[] 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 attr = attrs[attrIndex]; if (attr != null) { @@ -50,7 +88,379 @@ public abstract class EntityFullFunc { return attrs; } - public static EntityFullFunc create(Class type, Creator creator, Attribute[] attrs) { - return null; + static EntityFullFunc create(Class entityType, Creator creator, Attribute[] 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, + "", + "(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, + "", + "(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 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 newClazz = (Class) + 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); + } } } diff --git a/src/test/java/org/redkale/test/source/EntityFullFuncTest.java b/src/test/java/org/redkale/test/source/EntityFullFuncTest.java new file mode 100644 index 000000000..d888fe636 --- /dev/null +++ b/src/test/java/org/redkale/test/source/EntityFullFuncTest.java @@ -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 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 func2 = EntityBuilder.load(FullBean2.class).getFullFunc(); + Assertions.assertTrue(func2 != null); + EntityFullFunc 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 getColumnLabels() { + throw new UnsupportedOperationException("Not supported yet."); + } + }; +} diff --git a/src/test/java/org/redkale/test/source/FullBean2.java b/src/test/java/org/redkale/test/source/FullBean2.java new file mode 100644 index 000000000..8627dbb05 --- /dev/null +++ b/src/test/java/org/redkale/test/source/FullBean2.java @@ -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); + } +}