写于2017-09-14 21:41:32 由原有博客迁移
使用mapper查询数据时,每次给不同的parentId,但是却得到了相同的数据,我很是纳闷
起因:自己实现了一个适用于mybatis 自动生成mapper的基础业务类,主要是反射来写的,里面有两个成员字段,example和mapper(注意这就是造成后面一系列问题的根源),该类(BaseServiceImpl)的其中一个出错方法大致如下,
注意下面两行代码是后来改进的
public Object getExampleWithOrderConditionAndFilter(String condition, String orderMode,
Map<String, Map> filterConditions) throws Exception {
//利用反射来动态生成过滤条件
//内部类的CriteriaTypeLass需要由外部类的的Class获得 查看了源码criterClass有3个内部类,这里需要获取第2个
Class criteriaClass = null;
Class[] classes = example.getClass().getDeclaredClasses();
//在example的内部类中找到CriteriaTyperiteria的类
for (Class class1 : classes) {
if(class1.getName().contains("Criteria")) {
criteriaClass = class1;
break;
}
}
//利用反射来获取criteria
//com.colin.pojo.ArticleExampleTypexample.CriteriaTyperiteria criteria = example.createCriteriaTyperiteria();
//内部类不能new
//CriteriaType criteria = (CriteriaType) criteriaClass.newInstance();
//注意注意注意:下面两行代码是后来改进的
Method clear = example.getClass().getDeclaredMethod("clear");
clear.invoke(example);
Method createCriteria = example.getClass().getDeclaredMethod("createCriteria");
CriteriaType criteria = (CriteriaType) createCriteria.invoke(example);
if(filterConditions != null && filterConditions.size() > 0) {
Set keys = filterConditions.keySet();
for (Object key : keys) {
Map map = filterConditions.get(key);
Class paramterType = (Class) map.get("class");
//构建方法名字
String methodName = "and"+key+"EqualTo";
Method method = criteriaClass.getDeclaredMethod(methodName,paramterType);
//执行方法添加过滤条件
System.out.println("methodName"+methodName+"||||"+"参数:"+map.get("value"));
method.invoke(criteria, map.get("value"));
}
}
if(StringUtils.isNotBlank(condition) && StringUtils.isNotBlank(orderMode)) {
//设置排序条件 和排序模式
Method setOrderByClause = example.getClass().getDeclaredMethod("setOrderByClause", String.class);
//example.setOrderByCriteriaTypelause(condition+" "+orderMode);
setOrderByClause.invoke(example, condition+" "+orderMode);
}
return example;
}
该方法的作用就是获取一个带过滤和排序的example,但是这个example实际上是成员变量,也就是说整个类中的方法只用一个example
当我第一次调用改方法时会创建criteria(内部对象,用来加过滤条件),当我第二次调用改方法时,虽然传入了不同的参数,但是因为用的同一个example,所以其中的criteria对象还存在,过滤条件也就还在,也就是说我加入了不同的criteria,但是他们的过滤条件一样,只是值不一样
,这就造成了后来数据重复,因为原来的criteria对象还存在
总结:
1 一种没被验证的设计,对于我这种新手来说,没被验证极有可能会出错
2 不要把example对象作为一个成员变量,因为它极有可能带来数据重复的问题,旧数据未被清理