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

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]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值