|
Posted on 2010-01-13 15:32 長城 閱讀(403) 評論(0) 編輯 收藏
今日完成部門(department)和員工(employee)管理,由于昨天已經對增、刪、改、查摸了遍,所以今日的內容相對就比較簡單了。雖然簡單,仍然有需要注意的地方。經驗豐富的程序員,編寫的代碼十分優雅,這也是新人們嚴重不足的地方,當然我也應該加強這方面的能力。 不過說來也十分無聊,手動編寫OA項目已二天了。這兩天除了項目的架構與優雅的接口設計讓我感覺好些外,其他沒有什么讓我感覺愉快的。因為剩下的就是對數據庫的CRUD操作,無聊之極。但是我仍然需要努力學習,并在工作中總結經驗。將這部分的操作變得更簡潔一些。 一、部門管理 部門管理的難點在于,一個部門可以有一個“上級部門”與多個“下級部門”。對應的DispatchAciton有六個處理請求的方法。 1.顯示部門列表的list方法 顯示部門列表的方式:在頁面中顯示出頂級部門(沒有上級部門的部門),點擊其中的某個部門后顯示出對應部門的所有子部門。方法如下: DepartmentService deptServ = new DepartmentServiceImpl(); /** * 部門列表 */ public ActionForward list(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // 獲取頁面傳遞過來的上級部門ID Long parentId = null; if(request.getParameter("parentId")!=null) parentId = Long.parseLong(request.getParameter("parentId")); // 如果上級部門ID不為null則獲取對應部門的所有下級部門,否則獲取所有頂級部門 List<Department> list = null; if (parentId == null || this.deptServ.getById(parentId)==null) list = this.deptServ.getTopLevel(); else { Department dept = this.deptServ.getById(parentId); request.setAttribute("parent",dept); list = new ArrayList<Department>(dept.getChildren()); } // 將獲取后的部門列表存放于request的屬性中 request.setAttribute("departmentList", list); // 跳轉到顯示部門列表頁面 return mapping.findForward("list"); // list.jsp } | 這里我有必要說一下我的實現思想,我受以前面向過程編程的思想的影響沒有從完全面向對象的角度去解決這個實現。之前在老方的課堂上也是這樣,我沒有從完全面向對象的角度去思考他提出的問題,只想著最簡潔、最快速的面向過程實現方法。 我在實現上面的方法時也忽略的面向對象的思想,直接使用hibernate去查詢數據庫。事實上完全沒必要,因為部門之間的關系我們已經通過對象與映射文件描述出來了。直接使用對象的屬性就可以了!比如,獲取所有子部門。 2.跳轉到添加部門的addUI方法 /** * 跳轉至添加部門頁面 */ public ActionForward addUI(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // 獲取部門列表,以備指定被添加部門的上級部門 List<Department> list = this.deptServ.getTopLevel(); // getAllDepartmentList方法將部門以樹型的方法顯示 request.setAttribute("departmentList", DepartmentUtils.getAllDepartmentList(list)); // 跳轉至添加部門頁面 return mapping.findForward("saveUI"); // saveUI.jsp } | 這里只有以樹型顯示部門列表的方法是個小重點,我們使用了遞歸的方法實現的: public static List<Department> getAllDepartmentList( List<Department> topLevelList) { List<Department> list = new ArrayList<Department>(); formatDepartmentList(topLevelList, "┠", list); return list; } private static void formatDepartmentList(Collection<Department> deptList, String prefix, List<Department> reval) { for (Department dept : deptList) { // 新創建一個Department,防止修改hibernate緩存中的數據記錄。 Department newDept = new Department(); newDept.setId(dept.getId()); newDept.setName(prefix + dept.getName()); // 添加到返回值接收的List中 reval.add(newDept); // 遞歸調用子部門 formatDepartmentList(dept.getChildren(), " " + prefix, reval); } } | 3.添加部門的add方法 /** * 添加部門 */ public ActionForward add(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // 獲取表單提交過來的信息,轉成Department的Bean數據 DepartmentActionForm deptForm = (DepartmentActionForm) form; Department dept = new Department(); dept.setName(deptForm.getName()); dept.setParent(this.deptServ.getById(deptForm.getParentId())); // 保存數據 this.deptServ.save(dept); // 因為添加部門后我們需要顯示與被添加部門的所有同級部門,所以傳遞給顯示頁面上級部門的ID參數。 ActionForward af = mapping.findForward("toList"); return new ActionForward(af.getPath() + "&parentId=" + deptForm.getParentId(),af.getRedirect()); } | 4.跳轉到修改部門的editUI方法 /** * 跳轉到修改部門頁面 */ public ActionForward editUI(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // 獲取部門列表,以備指定被修改部門的上級部門 List<Department> list = this.deptServ.getTopLevel(); request.setAttribute("departmentList", DepartmentUtils.getAllDepartmentList(list)); // 將被修改部門的信息封裝到ActionForm中 DepartmentActionForm deptForm = (DepartmentActionForm) form; Department dept = this.deptServ.getById(deptForm.getId()); deptForm.setName(dept.getName()); if (dept.getParent() != null) deptForm.setParentId(dept.getParent().getId()); // 跳轉至修改部門頁面 return mapping.findForward("saveUI"); // saveUI.jsp } | 5.修改部門的edit方法 /** * 修改部門 */ public ActionForward edit(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // 獲取表單提交過來的信息,轉成Department的Bean數據 DepartmentActionForm deptForm = (DepartmentActionForm) form; // 先到數據庫中獲取被修改部門的記錄,是因為Bean與ActionForm屬性不一致。 Department dept = this.deptServ.getById(deptForm.getId()); dept.setName(deptForm.getName()); dept.setParent(this.deptServ.getById(deptForm.getParentId())); // 更新數據 this.deptServ.update(dept); // 因為更新部門后我們需要顯示與被添加部門的所有同級部門,所以在傳遞給顯示頁面上級部門的ID。 ActionForward af = mapping.findForward("toList"); return new ActionForward(af.getPath() + "&parentId=" + deptForm.getParentId(),af.getRedirect()); } | 6.刪除部門 /** * 刪除部門 */ public ActionForward del(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // 獲取部門id并刪除 String id = request.getParameter("id"); this.deptServ.delete(Long.parseLong(id)); // 因為刪除部門后我們需要顯示與被添加部門的所有同級部門,所以在傳遞給顯示頁面上級部門的ID。 ActionForward af = mapping.findForward("toList"); return new ActionForward(af.getPath() + "&parentId=" + request.getParameter("parentId"), af.getRedirect()); } | 上面這些方法十分簡單! 二、員工管理 員工管理的難點在于,員工具有一個部門和多個崗位的特性。我們通過指定員工對象的部門屬性和員工集合屬性,可以簡單的描述它們之間的關系。但添加或修改員工時,員工的部門和崗位的屬性如何顯示在頁面上呢?我們的頁面表單使用的是struts的html標簽,部門使用下拉列表框顯示,崗位使用列表框顯示。這兩個組件的選中項,只需要對應的id值即可。 這樣,我們就需要將員工的部門屬性和崗位集合屬于轉換為對應的id即可。我們將EmployeeActionForm對部門屬性定義為“Long departmentId;”,崗位集合屬性定義為“Set<Role> roleIdList;”,具體看下面的代碼。 1.員工列表 /** * 員工列表 */ public ActionForward list(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { List<Employee> employees = this.empServ.findAll(); request.setAttribute("employeeList", employees); return mapping.findForward("list"); // list.jsp } | 2.跳轉到添加員工頁面 /** * 添加員工頁面 */ public ActionForward addUI(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // 獲取部門和崗位列表,提供給添加員工時使用 List<Department> depts = this.deptServ.findAll(); List<Role> roles = this.roleServ.findAll(); request.setAttribute("departmentList", DepartmentUtils.getAllDepartmentList(depts)); request.setAttribute("roleList", roles); return mapping.findForward("saveUI"); // saveUI.jsp } | 3.添加員工 /** * 添加員工 */ public ActionForward add(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // 獲取頁面提交過來的員工信息 EmployeeActionForm empForm = (EmployeeActionForm) form; Employee emp = new Employee(); BeanUtils.copyProperties(emp, empForm); // 根據選中的部門id,獲取部門對象 emp.setDepartment(this.deptServ.getById(empForm.getDepartmentId())); // 根據選中的崗位id數組,獲取崗位對象集合 Set<Role> roles = new HashSet(this.roleServ.findByQuery(empForm.getRoleIdList())); emp.setRoles(roles); // 保存 this.empServ.save(emp); // 跳轉到顯示員工列表頁面 return mapping.findForward("toList"); } | 4.跳轉到修改員工頁面 /** * 修改員工頁面 */ public ActionForward editUI(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // 獲取被修改員工的信息 Long id = Long.parseLong(request.getParameter("id")); Employee emp = this.empServ.getById(id); // 將被修改員工的信息封裝到ActionForm中 EmployeeActionForm empForm = (EmployeeActionForm) form; BeanUtils.copyProperties(empForm, emp); // 獲取部門ID empForm.setDepartmentId(emp.getDepartment().getId()); // 根據崗位集合獲取對象崗位id數組 empForm.setRoleIdList(this.roleServ.getIdsByRoles(emp.getRoles())); // 獲取部門和崗位列表,并添加到request的屬性中 List<Department> depts = this.deptServ.findAll(); List<Role> roles = this.roleServ.findAll(); request.setAttribute("departmentList", DepartmentUtils.getAllDepartmentList(depts)); request.setAttribute("roleList", roles); // 跳轉到修改頁面 return mapping.findForward("saveUI"); // saveUI.jsp } | 5.修改員工 /** * 修改員工 */ public ActionForward edit(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // 先到數據庫中獲取被修改員工的記錄,是因為Bean與ActionForm屬性不一致。 Long id = Long.parseLong(request.getParameter("id")); Employee emp = this.empServ.getById(id); BeanUtils.copyProperties(emp, form); // 修改員工信息 this.empServ.update(emp); // 跳轉到顯示員工列表頁面 return mapping.findForward("toList"); } | 6.刪除員工 /** * 刪除員工 */ public ActionForward del(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // 根據刪除員工id,刪除員工 Long id = Long.parseLong(request.getParameter("id")); this.empServ.delete(id); // 跳轉到顯示員工列表頁面 return mapping.findForward("toList"); } | 7.特別注意 員工對象有一個入職時間的屬性,我們將這個屬性類型定義為java.util.Date類型。但保存或獲取SQL數據庫中的Date類型記錄時,我們需要轉換。但在程序中我們使用“BeanUtils.copyProperties(dest, orig);”方法將ActionForm中的數據拷貝到Dean對象中,此時我們需要為BeanUtils添加一個指定類型的轉換器,在HibernateSessionFilter的init方法中注冊轉換器: public void init(FilterConfig arg0) throws ServletException { ConvertUtils.register(new BeanDateConvert(), Date.class); System.out.println("過濾器HibernateSessionFilter注冊轉換器BeanDateConvert成功!"); } | 轉換器: import java.text.*; import java.util.Date; import org.apache.commons.beanutils.Converter; public class BeanDateConvert implements Converter { private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); public Object convert(Class clazz, Object value) { if(value == null) return null; if(value instanceof Date) return value; if(value instanceof String){ try { return this.sdf.parse((String) value); } catch (ParseException e) { e.printStackTrace(); return null; } } throw new IllegalArgumentException("不支持的類型:"+value.getClass().getName()); } } | 給員工分配帳戶,以及登陸與注銷管理在此就不總結了,因為它十分簡單。 三、JSP頁面整合與JQuery插件 現在,我們將這兩天編寫的內容使用framset整合到一起(index.jsp): <!-- 主頁面 --> <frameset border="0" rows="70px,20px,*" border="0" id="framesetRows"> <!-- 上部 --> <frame name="top" src="top.jsp" noresize="noresize" scrolling="no"> <!-- 分隔條 --> <frame name="top" src="top2.jsp" noresize="noresize" scrolling="no"> <!-- 下部 --> <frameset cols="200px,17px,*" border="0" id="framesetCols"> <!-- 左部 --> <frame name="left" src="left.jsp" noresize="noresize"> <!-- 分隔條 --> <frame name="middle" src="middle.jsp" noresize="noresize" scrolling="no"> <!-- 右部 --> <frame name="right" src="right.jsp" noresize="noresize"> </frameset> </frameset> | 我們在左部頁面使用了樹型,顯示各應用模塊和模塊詳細。在這里我們使用的是xtree這個JQuery插件。使用JQuery插件非常簡單,直接在網頁中引入插件的js文件,然后調用相關接口即可使用插件: <script type="text/javascript" src="${pageContext.request.contextPath}/script/xtree/xtree.js"></script> <link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/script/xtree/xtree.css" /> <script type="text/javascript"> var tree = new WebFXTree("導航菜單"); var item0 = tree.add(new WebFXTreeItem("Welcome, [${user.employee.name}]")); item0.add(new WebFXTreeItem("登錄", "<html:rewrite action='/user?method=loginUI'/>", null, null, null, "right")); item0.add(new WebFXTreeItem("注銷", "<html:rewrite action='/user?method=logout'/>", null, null, null, "right")); var item3 = tree.add(new WebFXTreeItem("組織機構管理")); var item = item3.add(new WebFXTreeItem("部門管理", "<html:rewrite action='/dept?method=list'/>", null, null, null, "right")); item3.add(new WebFXTreeItem("崗位管理", "<html:rewrite action='/role?method=list'/>", null, null, null, "right")); item3.add(new WebFXTreeItem("員工管理", "<html:rewrite action='/emp?method=list'/>", null, null, null, "right")); document.write(tree); tree.expandAll(); </script> | 我們也有在添加員工時為入職時間指定了一個日期框的插件,使用起來非常方便。 OK,上邊就是今天的內容!還有OA項目還有三天,接下來的三天主要使用JBPM來完成審批管理、審批流轉、表單查詢功能。 以前學的零散的知識,現在用到了一起,感覺very fine!
|