ORM尝试二 利用反射获取类信息

来源:互联网 发布:泳裤什么牌子好 知乎 编辑:程序博客网 时间:2024/05/22 15:29

ORM尝试二 利用反射获取类信息

一 思路:

可以根据

  • 仅仅是类名
  • 类的实例

获取类的信息


而我们需要获取到的信息有:

  • 类名
  • 成员变量的名称
  • 成员变量的类型
  • 成员变量的 getter 和 setter
  • 成员变量的 value

二 解决方法:

1 建立一个类:

public class SimpleField {    private String klassName;    private String fieldName, fieldType, getterMethodName, fieldSetter;    private Object fieldValue;}

2 根据类名:

public SimpleField(String klassName, String fieldName, String fieldType) {    this.klassName = klassName;    this.fieldName = fieldName;    this.fieldType = fieldType;    buildSetter(fieldName);    buildGetter(fieldName, fieldType);}

3 根据类实例:

public SimpleField(Object object, String fieldName, String fieldType) {    this.klassName = object.getClass().getName();    this.fieldName = fieldName;    this.fieldType = fieldType;    buildSetter(fieldName);    buildGetter(fieldName, fieldType);    buildValue(object, fieldName, fieldType);}

4 buildSetter:

private void buildSetter(String fieldName) {    StringBuilder builder = new StringBuilder();    builder.append("set");    builder.append(fieldName.substring(0, 1).toUpperCase()).append(            fieldName.substring(1));    // 字符串拼接获取到set方法    this.fieldSetter = builder.toString();}

5 buildgetter:

private void buildGetter(String fieldName, String fieldType) {    StringBuilder builder = new StringBuilder();    if (DataBaseUtil.JAVA_BOOLEAN.equals(fieldType)) {        builder.append("is");    } else {        builder.append("get");    }    builder.append(fieldName.substring(0, 1).toUpperCase()).append(            fieldName.substring(1));    // 字符串拼接获取到get方法    this.getterMethodName = builder.toString();}

6 buildValue:

private void buildValue(Object object, String fieldName, String fieldType) {    Method getterMethod = null;    try {        getterMethod = object.getClass().getMethod(getterMethodName);        // 根据方法名得到方法        switch (fieldType) {        case DataBaseUtil.JAVA_INT:            this.fieldValue = (int) getterMethod.invoke(object);            // 表示object.getterMethod() 返回值是int类型 以下等同            break;        case DataBaseUtil.JAVA_LONG:            this.fieldValue = (long) getterMethod.invoke(object);            break;        case DataBaseUtil.JAVA_SHORT:            this.fieldValue = (short) getterMethod.invoke(object);            break;        case DataBaseUtil.JAVA_FLOAT:            this.fieldValue = (float) getterMethod.invoke(object);            break;        case DataBaseUtil.JAVA_DOUBLE:            this.fieldValue = (double) getterMethod.invoke(object);            break;        case DataBaseUtil.JAVA_STRING:            this.fieldValue = (String) getterMethod.invoke(object);            break;        case DataBaseUtil.JAVA_BOOLEAN:            this.fieldValue = (boolean) getterMethod.invoke(object);            break;        case DataBaseUtil.JAVA_LONGTEXT:            this.fieldValue = (String) getterMethod.invoke(object);            break;        default:            break;        }    } catch (NoSuchMethodException | SecurityException e) {        e.printStackTrace();    } catch (IllegalAccessException e) {        e.printStackTrace();    } catch (IllegalArgumentException e) {        e.printStackTrace();    } catch (InvocationTargetException e) {        e.printStackTrace();    }}

三 获取到klassName, fieldName 和 fieldType

同样是

  • 根据类名
  • 根据类实例

1 根据类名:

/** *  * @param klassName *            首先是根据类名,没有相应变量值,获取类信息 * @param needId *            在数据库中,一般ID是自增类型,可以在这里排除掉 */public KlassMessage(String klassName, boolean needId) {    Class<?> klass = getKlass(klassName);    String[] longtexts = {};    // 判断是否存在LongTextHelper注解,    // 长文本在MYSQL中的类型为text,而段文本为varchar    if (klass.getAnnotation(LongTextHelper.class) != null) {        longtexts = klass.getAnnotation(LongTextHelper.class).value();    }    Field[] fieldArray = klass.getDeclaredFields();    String fieldName = "";    String fieldType = "";    int length = fieldArray.length;    for (int i = 0; i < length; i++) {        boolean isNotStatic = !Modifier.isStatic(fieldArray[i]                .getModifiers());        boolean isNotFinal1 = !Modifier.isFinal(fieldArray[i]                .getModifiers());        // 排除static和final变量        if (isNotStatic && isNotFinal1) {            fieldName = fieldArray[i].getName();            fieldType = fieldArray[i].getGenericType().toString();            if (!_ID.equals(fieldName)) {                if (isInAnArray(fieldName, longtexts)) {                    fieldType = DataBaseUtil.JAVA_LONGTEXT;                }                simpleFields.add(new SimpleField(klassName, fieldName,                        fieldType));            } else if (_ID.equals(fieldName) && needId) {                simpleFields.add(new SimpleField(klassName, fieldName,                        fieldType));            }        }    }}

2 根据类的实例:

/** * @param object *            根据一个类的实例,获取类信息 * @param needId *            在数据库中,一般ID是自增类型,可以在这里排除掉 */public KlassMessage(Object object, boolean needId) {    Class<? extends Object> klass = object.getClass();    Field[] fieldArray = klass.getDeclaredFields();    String fieldName = "";    String fieldType = "";    String[] longtexts = {};    // 判断是否存在LongTextHelper注解,    // 长文本在MYSQL中的类型为text,而短文本为varchar    if (klass.getAnnotation(LongTextHelper.class) != null) {        longtexts = klass.getAnnotation(LongTextHelper.class).value();    }    int length = fieldArray.length;    for (int i = 0; i < length; i++) {        boolean isNotStatic = !Modifier.isStatic(fieldArray[i]                .getModifiers());        boolean isNotFinal1 = !Modifier.isFinal(fieldArray[i]                .getModifiers());        // 排除static和final变量        if (isNotStatic && isNotFinal1) {            fieldName = fieldArray[i].getName();            if (isInAnArray(fieldName, longtexts)) {                fieldType = DataBaseUtil.JAVA_LONGTEXT;            } else {                fieldType = fieldArray[i].getGenericType().toString();            }            if (!_ID.equals(fieldName)) {                simpleFields.add(new SimpleField(object, fieldName,                        fieldType));            } else if (_ID.equals(fieldName) && needId) {                simpleFields.add(new SimpleField(object, fieldName,                        fieldType));            }        }    }}

3 注解:

import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.RUNTIME)public @interface LongTextHelper {    String[] value();}

注解的使用:在类定义前加上:

@LongTextHelper(value = { "fieldName" })

4 判断变量是否在注解的value当中:

/** * judge if a String value exists in a String array *  * @param targetString *            target string * @param targetStrings *            target string array * @return true if exists, false otherwise */private static boolean isInAnArray(String targetString,        String[] targetStrings) {    boolean isIn = false;    for (String string : targetStrings) {        if (targetString.equals(string)) {            isIn = true;        }    }    return isIn;}

四 测试:

package testorm;import java.util.List;import com.databasehelper.LongTextHelper;import com.klass.KlassMessage;import com.klass.SimpleField;@LongTextHelper(value = { "singature" })public class Student {    private int age, id;    private String name;    private String singature; //签名是长文本    private boolean handsome;    public boolean isHandsome() {        return handsome;    }    public void setHandsome(boolean handsome) {        this.handsome = handsome;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getSingature() {        return singature;    }    public void setSingature(String singature) {        this.singature = singature;    }    public Student() {        this.age = 20;        this.handsome = true;        this.name = "granton";        this.singature = "this is my singature";    }    public static void main(String[] args) {        Student student = new Student();        KlassMessage klassMessage = new KlassMessage(student, false);        List<SimpleField> simpleFields = klassMessage.getSimpleFields();        System.out.println("using object:");        for (SimpleField simpleField : simpleFields) {            System.out.println(simpleField.toString());        }        System.out.println("this is devide line------");        System.out.println("using class name:");        KlassMessage klassMessage2 = new KlassMessage("testorm.Student", true);        List<SimpleField> simpleFields2 = klassMessage2.getSimpleFields();        for (SimpleField simpleField : simpleFields2) {            System.out.println(simpleField.toString());        }    }}

运行结果:

using object:[klassName=testorm.Student, fieldName=age, fieldType=int, fieldGetter=getAge, fieldSetter=setAge, fieldValue=20][klassName=testorm.Student, fieldName=name, fieldType=class java.lang.String, fieldGetter=getName, fieldSetter=setName, fieldValue=granton][klassName=testorm.Student, fieldName=singature, fieldType=text, fieldGetter=getSingature, fieldSetter=setSingature, fieldValue=this is my singature][klassName=testorm.Student, fieldName=handsome, fieldType=boolean, fieldGetter=isHandsome, fieldSetter=setHandsome, fieldValue=true]this is devide line------using class name:[klassName=testorm.Student, fieldName=age, fieldType=int, fieldGetter=getAge, fieldSetter=setAge, fieldValue=null][klassName=testorm.Student, fieldName=id, fieldType=int, fieldGetter=getId, fieldSetter=setId, fieldValue=null][klassName=testorm.Student, fieldName=name, fieldType=class java.lang.String, fieldGetter=getName, fieldSetter=setName, fieldValue=null][klassName=testorm.Student, fieldName=singature, fieldType=text, fieldGetter=getSingature, fieldSetter=setSingature, fieldValue=null][klassName=testorm.Student, fieldName=handsome, fieldType=boolean, fieldGetter=isHandsome, fieldSetter=setHandsome, fieldValue=null]
0 0