最近在做一个数据清洗功能,由于老系统数据录入不规范,通过身份证号查询表,会返回一个人员的多条记录,其中有些同一字段属性值各不相同。
数据清洗功能目的在于查询出人员的多条记录,遍历生成的实体类中的所有属性,把属性相同但值不同的字段全部展示出来,通过单选按钮的形式,让操作人选择一个正确的属
性,最后把全部选择正确的数据发回后台,重新更新数据库,并只保留一条数据,另外几条做逻辑删除。
主要难点就在于遍历属性及筛选出有差异的属性值,解决方法如下:
/** * 根据身份证号,查询从业人员基本信息(可能有多条,多条时要进行数据清洗) * 筛选出多条记录中有差异的部分,比如 名字不同、电话号码不同,发回页面进行数据清洗 * @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 方法,组装成实体类,调用更新方法即可。