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]