Java泛型反射实践
最近项目中刚好有个机会尝试反射的使用,因为项目时间紧没花太多时间去做优化,毕竟优化后又得一轮大测试,写下来也是为了方便以后使用时能又个参考;
贴代码
/**
* @Author: xiaoyao
* @Description: 将model实体转成example
* @DateTime: 2020/5/22 11:58
* @Param: model 传入的实体对象
* @Param: exampleClazz 要转换的example类模板
* @Param: isPage 是否使用分页
*/
private static <T, S extends AbstractExample> S modelToExample(T model, Class<S> exampleClazz, Boolean isPage){
S example = null;
try {
example = exampleClazz.newInstance();
example.setOrderByClause(" create_time desc ");
Class<? extends Object> clazz = model.getClass();
// 得到实体泛型所有属性
Field[] field = clazz.getDeclaredFields();
// 创建 Criteria
Method mCriteria = exampleClazz.getDeclaredMethod("createCriteria");
GeneratedCriteria criteria = (GeneratedCriteria)mCriteria.invoke(example);
for(int i=0;i<field.length;i++){
// 设置可以访问私有变量
field[i].setAccessible(true);
// 获取属性的名字
String name = field[i].getName();
// 实体类中的序列化属性没有Get方法
if(name.equals("serialVersionUID"))
continue;
// 将属性名字的首字母大写
name = name.replaceFirst(name.substring(0, 1), name.substring(0, 1).toUpperCase());
// 组装Get方法
Method m = clazz.getDeclaredMethod("get" + name);
// 调用Get方法
Object o = m.invoke(model);
// 判断属性值是否为空
if(o == null){
continue;
}
if(!isPage && ("PageSize".equals(name))){
continue;
}
if(!isPage && ("PageStart".equals(name))){
continue;
}
if ("PageSize".equals(name)) {
example.setPageSize(Integer.parseInt(o.toString()));
continue;
}
if ("PageStart".equals(name)) {
example.setPageStart(Integer.parseInt(o.toString()));
continue;
}
Method mEqualTo = null;
if ("Id".equals(name)){
criteria.andIdEqualTo(Long.parseLong(o.toString()));
} else
// 判断自定义注解,这里是判断实体类里的自定义注解,从而判断使用何种Where条件
if (field[i].isAnnotationPresent(Like.class)) {
mEqualTo = criteria.getClass().getDeclaredMethod("and" + name + "Like", Class.forName(o.getClass().getTypeName()));
o = "%" + o + "%";
} else if (field[i].isAnnotationPresent(Less.class)) {
mEqualTo = criteria.getClass().getDeclaredMethod("and" + name + "LessThan", Class.forName(o.getClass().getTypeName()));
} else if (field[i].isAnnotationPresent(Greater.class)) {
mEqualTo = criteria.getClass().getDeclaredMethod("and" + name + "GreaterThan", Class.forName(o.getClass().getTypeName()));
} else if (field[i].isAnnotationPresent(LessOrEqual.class)) {
mEqualTo = criteria.getClass().getDeclaredMethod("and" + name + "LessThanOrEqualTo", Class.forName(o.getClass().getTypeName()));
} else if (field[i].isAnnotationPresent(GreaterOrEqual.class)) {
mEqualTo = criteria.getClass().getDeclaredMethod("and" + name + "GreaterThanOrEqualTo", Class.forName(o.getClass().getTypeName()));
} else {
mEqualTo = criteria.getClass().getDeclaredMethod("and" + name + "EqualTo", Class.forName(o.getClass().getTypeName()));
}
// 调用构建的criteria方法,将实体类的值设置到criteria里
mEqualTo.invoke(criteria, o);
}
} catch (Exception e) {
return example;
}
return example;
}
/**
* @Author: xiaoyao
* @Description: 将model实体转成example
* @DateTime: 2020/5/22 11:58
* @Param: model 传入的实体对象
* @Param: exampleClazz 要转换的example类模板
*/
public static <T, S extends AbstractExample> S modelToExample(T model, Class<S> exampleClazz){
return modelToExample(model, exampleClazz, false);
}
/**
* @Author: xiaoyao
* @Description: 将model实体转成example,带分页
* @DateTime: 2020/5/22 11:58
* @Param: model 传入的实体对象
* @Param: exampleClazz 要转换的example类模板
*/
public static <T, S extends AbstractExample> S modelToExamplePage(T model, Class<S> exampleClazz){
return modelToExample(model, exampleClazz, true);
}