最近在做一个数据清洗功能,由于老系统数据录入不规范,通过身份证号查询表,会返回一个人员的多条记录,其中有些同一字段属性值各不相同。
数据清洗功能目的在于查询出人员的多条记录,遍历生成的实体类中的所有属性,把属性相同但值不同的字段全部展示出来,通过单选按钮的形式,让操作人选择一个正确的属
性,最后把全部选择正确的数据发回后台,重新更新数据库,并只保留一条数据,另外几条做逻辑删除。
主要难点就在于遍历属性及筛选出有差异的属性值,解决方法如下:
/**
* 根据身份证号,查询从业人员基本信息(可能有多条,多条时要进行数据清洗)
* 筛选出多条记录中有差异的部分,比如 名字不同、电话号码不同,发回页面进行数据清洗
* @return
* chenfx
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
@RequiresPermissions("basinfo:qlfctBasInfo:view")
@RequestMapping(value = "selectDifferenceOfBasInfoList")
@ResponseBody
public Object selectDifferenceOfBasInfoList(QlfctBasInfo qlfctBasInfo, HttpServletRequest request, HttpServletResponse response, Model model) throws IllegalArgumentException, IllegalAccessException{
String selectIdNo = request.getParameter("selectIdNo"); //操作人选择的身份证号
String selectId = request.getParameter("selectId"); //操作人选择的从业人员id
List<QlfctBasInfo> basInfoList = (List<QlfctBasInfo>)request.getSession().getAttribute("basInfoList"); //从session中取出之前查询到的从业人员集合
List<List<Object>> difference = new ArrayList<List<Object>>(); //属性存在差异的字段集合
if(basInfoList != null && basInfoList.size()>0){
Field[] fields = QlfctBasInfo.class.getDeclaredFields(); //取得 QlfctBasInfo 实体类的所有属性集合
//遍历属性
for(int i=0; i<fields.length; i++){
Field f = fields[i];
f.setAccessible(true);
//遍历从业人员信息实体类所有属性,所有从业人员的同一个属性保存在同一个数组中
//其中第一个元素,为属性名,第二个元素,为属性注释,之后的为属性值
//集合结构如 : name 姓名 张三 张四
HashSet<Object> hashset = new HashSet<Object>(); //把从业人员集合遍历出来的不同对象属性放入set中,去重复。
for(int k = 0;k<basInfoList.size();k++){
if(f.get(basInfoList.get(k)) != null && !f.get(basInfoList.get(k)).equals("")){
hashset.add(f.get(basInfoList.get(k))); //取得属性值
}
}
if(hashset.size() > 1){ //当属性set集合有值时,且有不同值时
List<Object> li = new ArrayList<Object>(); //属性集合
li.add(f.getName()); //集合中第一个元素,存放属性名 如 name
String attrMark = (String)QlfctBasInfo.map.get(f.getName()); //集合中第二个元素,存放属性注释 如 姓名
li.add(attrMark);
//TODO 编码和label的转换
for(Object o : hashset){ //将 set 中的元素遍历,放入属性集合中
li.add(o);
}
difference.add(li); //把有存在差异的属性集合,放入difference差异字段属性集合
}
}
}
return difference;
}
为了方便页面显示,在实体类中使用设置一个MAP,以 属性名 : 注释 的形式保存。
String attrMark = (String)QlfctBasInfo.map.get(f.getName()); //集合中第二个元素,存放属性注释 如 姓名
关键点:
Field[ ] fields = QlfctBasInfo.class.getDeclaredFields( ) ;
取得实体类的所有属性集合。
String attrName = fields[0].getName() ;
获得属性集合中第一个属性的名字
Object attrValue = fields[0].get(qlfctBasInfo) ;
获得属性集合中第一个属性的值
Field field = QlfctBasInfo.class.getDeclaredField(“name” ) ; 取得实体类中"name"字段的Field对象
field.set(qlfctBasInfo,"无诤三昧");
执行
实体类中"name"字段的 set 方法
从页面发回来的数据,属性名和属性值一一对应,再循环调用 Field 的set 方法,组装成实体类,调用更新方法即可。