之前,本人分享过一篇关于级联搜索框查询的Beta版(尽管这种查询方式太不人性化,但是既然做了,就要有始有终)。链接如下:技术实现——联动菜单并保持数据的Demo。
在上面这篇文章中,只对技术的实现思路做了较为详细的讲解,并没有考虑它的实用性与通用性。同时,也由于本人于此的业务逻辑较少,所以并没有及时对它进行封装。延误至今,希望得到大家的谅解。
在上述Demo中,大家如果想要使用该功能,必须在后台做如下实现:
//注入对应服务 private ICommonServiceBean evaluateInfoService; /** * @MethodName : getTeacherByCollegeId * @Description : 根据学院Id查询教师 * @param collegeId * @return */ public String getTeacherByCollegeId(String collegeId) { String out = ""; List<TeacherAllInfo> teachers = evaluateInfoService .findTeacherByCollegeId(collegeId); if (teachers != null && teachers.isEmpty()) { out = "[{\"id\":\"" + " " + "\",\"name\":\"" + "--请选择--" + "\"},"; for (int i = 0; i < teachers.size(); i++) { out += "{\"id\":\"" + teachers.get(i).getTeacherId() + "\",\"name\":\"" + teachers.get(i).getTeacherName() + "\"},"; } out = out.substring(0, out.length() - 1) + "]"; } return out; }
上述代码是根据学院Id查询教师,如果想要实现根据教师Id查询课程功能,那么我们就要需要写一个与上述方法完全类似的方法,代码高度重复,且没有做到代码的复用。修改起来非常费劲,不利于统一管理。
下面是我做的封装。这个封装实现的中心思想是:利用了Java的反射机制,从泛型中取出Java对象。
private ICalendarServiceBean calendarService; //注入对应服务 private ICommonServiceBean evaluateInfoService; /** * @MethodName : getChildByFatherId * @Description : 根据上级Id查询子级信息 * @param id 上级Id * @param evaluateInfoService 传入注入的服务 * @return 拼接完整的串 */ public String getChildByFatherId(String id,ICommonServiceBean evaluateInfoService){ return getChildByFatherId(id,evaluateInfoService,"id","name"); } /** * @MethodName : getChildByFatherId * @Description : 根据上级Id查询子级信息 * @param id 上级Id * @param evaluateInfoService 传入注入的服务 * @param oId 实体中id属性名,默认为id * @param oName 实体中name属性名,默认为name * @return 拼接完整的串 */ public String getChildByFatherId(String id, ICommonServiceBean evaluateInfoService,String oId,String oName) { String out = ""; List<?> infoLists = evaluateInfoService.findTeacherByCollegeId(id); if (infoLists != null && infoLists.isEmpty()) { out = "[{\"id\":\"" + " " + "\",\"name\":\"" + "--请选择--" + "\"},"; for (int i = 0; i < infoLists.size(); i++) { try { // 获取对象中名为“id”的元素 Field ids = infoLists.get(i).getClass().getDeclaredField(oId); // 获取对象中名为"name"元素 Field names = infoLists.get(i).getClass().getDeclaredField(oName); if (!ids.isAccessible()) { ids.setAccessible(true); } if (!names.isAccessible())// 判断该对象是否可以访问 { names.setAccessible(true);// 设置为可访问 } String strId = ids.get(infoLists.get(i)).toString(); String strName = names.get(infoLists.get(i)).toString(); out += "{\"id\":\"" + strId + "\",\"name\":\"" + strName + "\"},"; } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (SecurityException e1) { e1.printStackTrace(); } catch (NoSuchFieldException e1) { e1.printStackTrace(); } out = out.substring(0, out.length() - 1) + "]"; } } return out; }
有了这里的封装,我们在使用时只需要如下:
/** * @MethodName : getTeacherByCollegeId * @Description : 根据学院Id查询教师 * @param collegeId * @return */ public String getTeacherByCollegeId(String collegeId) { return getChildByFatherId(collegeId,evaluateInfoService); } /** * @MethodName : getCourseByTeacherId * @Description : 根据教师Id查询课程信息 * @param teacherId * @return */ public String getCourseByTeacherId(String teacherId) { return getChildByFatherId(teacherId, evaluateInfoService, "teacherId", "teacherName"); }
以上就是我对后台实现的封装,对于前台JavaScript调用部分,你仍然可以自己做一下优化,写出更加漂亮的代码。
通过反射,我们就将不变的东西封装了起来,拥抱了变化。人家都说“反射反射,程序员的快乐。”今天,你快乐了吗?