Java SSM練手小項目-手把手帶你搭建一個基于SSM框架的人力資源管理后臺系統(tǒng)

Java SSM練手小項目-手把手帶你搭建一個基于SSM框架的人力資源管理后臺系統(tǒng)

置頂2018年03月11日 00:22:54

閱讀數(shù):872

前言

相信很多小伙伴在學習完SSM三大架構以后,不知道該如何找到一個簡單容易上手的項目進行實戰(zhàn)訓練,經(jīng)常在博客上看到一個不錯的項目下載下來以后全部都是代碼,無處下手。因此本文力求以最簡單易懂的項目結構和代碼搭建一個還較為完整(即從登錄到退出的整個流程)的后臺系統(tǒng)。(適合新手)

整個項目的操作流程動態(tài)圖如下(由于CSDN對上傳圖片大小有限制,這里錄制的gif畫面很不清晰,點擊圖片查看更清晰):?

(點擊圖片查看)

項目的整體結構:?


用到的技術點有:

框架:SSM

數(shù)據(jù)庫:MySQL

前端框架:Bootstrap快速搭 搭建JSP頁面

項目管理:MAVEN

開發(fā)工具:IntellijIDEA

開發(fā)環(huán)境:Windows

從這個項目中你可以完整獨立地體驗從前端到后臺的搭建過程,以及使用SSM框架完成后臺的CRUD整個流程。

一、準備

準備部分主要包括數(shù)據(jù)庫建表、SSM框架的搭建啟動。?

1 數(shù)據(jù)庫建表?

tbl_emp表:

DROPTABLEIFEXISTS`tbl_emp`;CREATETABLE`tbl_emp`(`emp_id`int(11) UNSIGNEDNOTNULLauto_increment,`emp_name`VARCHAR(22)NOTNULLDEFAULT'',`emp_email`VARCHAR(256)NOTNULLDEFAULT'',`gender`CHAR(2)NOTNULLDEFAULT'',`department_id`int(11)NOTNULLDEFAULT0,PRIMARYKEY(`emp_id`)) ENGINE=INNODBDEFAULTCHARSET=UTF8;

tbl_dept表:

DROPTABLEIFEXISTS`tbl_dept`;CREATETABLE`tbl_dept`(`dept_id`int(11) UNSIGNEDNOTNULLauto_increment,`dept_name`VARCHAR(255)NOTNULLDEFAULT'',`dept_leader`VARCHAR(255)NOTNULLDEFAULT'',PRIMARYKEY(`dept_id`)) ENGINE=InnoDBDEFAULTCHARSET=utf8;


對應的實體類見bean/Employee.java和bean/Department.java。?

(在測試部分可以將數(shù)據(jù)插入到表中)

2 SSM項目搭建與啟動?

(1)本次項目使用的是MAVEN進行JAR包的管理,首先導入項目中可能用到的依賴包:?

見pom.xml.

(2)Web項目的配置文件:web.xml:?

見WEB-INF/web.xml.

(3)Spring容器配置文件:applicationContext.xml:?

見resources/applicationContext.xml.

(4)SpringMVC配置文件:springmvc.xml:?

見resources/springmvc.xml.

3 測試?

寫好上述配置文件后,可以在controller目錄下新建TestController.java文件和WEB-INF/jsp/test.jsp,啟動容器測試是否成功。

二、DAO層代碼完成與測試

這一章主要完成數(shù)據(jù)庫底層的CRUD代碼實現(xiàn)與測試工作。?

1. MyBasits配置文件?

見resources/MyBatis.xml.

2. DAO層代碼?

首先編寫實體類Employee 與 表tbl_emp相關操作代碼。?

EmployeeMapper.java主要接口有:

int deleteOneById(@Param("empId")Integer empId);

int updateOneById(@Param("empId")Integer empId,? ? ? ? ? ? ? ? ? @Param("employee")Employee employee);

int insertOne(Employee employee);? ? ? ? ?

Employee selectOneById(@Param("empId")Integer empId);

Employee selectOneByName(@Param("empName")String empName);// 查詢帶有部門信息的EmployeeEmployee selectWithDeptById(@Param("empId")Integer empId);// 分頁查詢List selectByLimitAndOffset(@Param("limit")Integer limit,@Param("offset")Integer offset);

int countEmps();


具體實現(xiàn)參考EmployeeMapper.java與EmployeeMapper.xml中代碼。

寫完后需要對實現(xiàn)的代碼進行測試,以驗證代碼的正確性。?

測試用例代碼見EmployeeMapperTest.java。

類似地,?

實體類Department與 表tbl_dept相關操作代碼實現(xiàn)也如上類似,具體實現(xiàn)見DepartmentMapper.java 與 DepartmentMapper.xml,測試用例代碼見DepartmentMapperTest.java。

三、前端頁面的搭建

前端頁面實現(xiàn)的最終效果如下。?

主頁面:?

員工操作頁面(部門操作頁面類似):?

(點擊圖片查看)

最后加上一個登陸頁面(比較簡單的頁面加上最簡單的登錄判斷):?

(點擊圖片查看)

主要就是采用Bootstrap3去搭建這個前端頁面,然后再利用SSM框架+JSP完成從前端到后端的整個流程。?

下面首先Bootstrap3去搭建前端頁面。

1 主頁面的靜態(tài)搭建

主頁面的HTML代碼實現(xiàn)放在webapp/static/html/hrms_main.html,(此處僅僅為了方便查看和參考)。?

整個主頁面完成后,分別將其中公共部分的代碼提取出來,如導航欄,左側欄,尾部這3個部分都屬于公共部分,?

分別見hrms_head.html、hrms_foot.html、hrms_leftsidebar.html三個部分。

2 公共頁面的JSP實現(xiàn)及分層

下面將上述公共部分的HTML代碼用JSP實現(xiàn),詳細見WEB-INF/jsp/commom目錄下的head.jsp、foot.jsp、leftsidebar.jsp。

然后實現(xiàn)主頁面的內容,主要包括三個公共部分(導航欄+左側欄+尾部+輪播部分),實現(xiàn)效果如下:?

(點擊圖片查看)

新建main.jsp,將上述三個公共部分的代碼用?

<<%@ include file="./commom/xx.jsp"%>>引入,再用Bootstrap實現(xiàn)輪播圖部分即可,具體實現(xiàn)見main.jsp中代碼。

3 員工操作/部門操作的靜態(tài)頁面實現(xiàn)

員工操作頁面與主頁面3個公共部分相同,不同之處在于中間部分展示的是員工信息的表格顯示,而主頁面是一個輪播圖。?

(點擊圖片查看)

下面就將實現(xiàn)employeePage的頁面,詳細代碼見employeePage.jsp(即將main.jsp中的輪播部分換成員工表單顯示部分即可)。

(為了方便對比與查看,將實現(xiàn)的HTML部分代碼留在了項目目錄中,?

實現(xiàn)的HTML代碼見WEB-INF/static/html/hrms_employee.html。?

相應的部門顯示的頁面類似,?

實現(xiàn)的HTML代碼見WEB-INF/static/html/hrms_department.html。?

然后將上述代碼分別用JSP頁面實現(xiàn),即對應的employeePage.jsp和departmentPage.jsp。)

四、員工CRUD操作前后端實現(xiàn)

1 員工信息查詢的數(shù)據(jù)顯示

頁面搭建完成以后,就要將從后臺獲取到的數(shù)據(jù)展示在對應的頁面中。頁面數(shù)據(jù)展示部分主要實現(xiàn)是利用JSP的JSTL表達式和AJAX+jQuery,將從后臺獲取到的數(shù)據(jù)顯示在頁面對應的位置。

由于部門操作與員工操作類似,下面主要講解員工顯示頁面的實現(xiàn)。?

整個流程是從數(shù)據(jù)庫中查詢到數(shù)據(jù)后,放在SpringMVC的ModelAndView中,然后前端通過JSTL就可以解析獲取到的結果集。?

(1)首先寫一個JSON相關的操作類:JsonMsg.java。?

(2)業(yè)務操作:EmployeeService.java;?

(3)Controller類:EmployeeController.java;?

@RequestMapping(value = "/getEmpList", method = RequestMethod.GET)

? ? public ModelAndView getEmp(@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo){

? ? ? ? ModelAndView mv = new ModelAndView("");

? ? ? ? int limit = 5;

? ? ? ? // 記錄的偏移量(即從第offset行記錄開始查詢),? ? ? ? // 如第1頁是從第1行(offset=(21-1)*5=0,offset+1=0+1=1)開始查詢;? ? ? ? // 第2頁從第6行(offset=(2-1)*5=5,offset+1=5+1=6)記錄開始查詢? ? ? ? int offset = (pageNo-1)*limit;

? ? ? ? //獲取指定頁數(shù)包含的員工信息? ? ? ? List employees = employeeService.getEmpList(offset, limit);

? ? ? ? //獲取總的記錄數(shù)? ? ? ? int totalItems = employeeService.getEmpCount();

? ? ? ? //獲取總的頁數(shù)? ? ? ? int temp = totalItems / limit;

? ? ? ? int totalPages = (totalItems % limit == 0) ? temp : temp+1;

? ? ? ? //當前頁數(shù)? ? ? ? int curPage = pageNo;

? ? ? ? //將上述查詢結果放到Model中,在JSP頁面中可以進行展示? ? ? ? mv.addObject("employees", employees)

? ? ? ? ? ? ? ? .addObject("totalItems", totalItems)

? ? ? ? ? ? ? ? .addObject("totalPages", totalPages)

? ? ? ? ? ? ? ? .addObject("curPage", curPage);

? ? ? ? return mv;

? ? }


然后在employeePage.jsp頁面上將后端的Modal中數(shù)據(jù)取出來進行顯示。?

主要代碼有:

${emp.empId} ${emp.empName} ${emp.empEmail} ${emp.gender == "M"? "女": "男"} ${emp.department.deptName} 編輯 刪除

當前第${curPage}頁,共有${totalPage}頁,總記錄數(shù)${totalItems}條。


(4)分頁欄的代碼實現(xiàn)。?

分頁欄完成效果如下:?

(點擊圖片查看)

關于分頁欄需要完成的需求有:

當前頁需要激活(主要是頁面上的1,2,3,4,5頁);

在首頁(第1頁)的時候,<< 禁止點擊;

在末頁(最后一頁)的時候,>>禁止點擊;

默認顯示首頁數(shù)據(jù);

首頁,上一頁,末頁,下一頁添加事件,顯示對應頁碼數(shù)據(jù)

中間頁每一頁,為其添加點擊事件,并跳轉到對應頁面;

左邊信息欄中當前第X頁需要根據(jù)點擊的頁數(shù)同步顯示。

主要的代碼實現(xiàn)都是在前端使用jQuery+JSTL實現(xiàn)的。代碼如下:

此處代碼略


以及對應的jQuery實現(xiàn)上一頁、下一頁的操作:

$(function(){//上一頁varcurPage = ${curPage};vartotalPages = ${totalPages};? ? ? ? $(".prePage").click(function(){if(curPage >1){varpageNo = curPage-1;? ? ? ? ? ? ? ? $(this).attr("href","/emp/getEmpList?pageNo="+pageNo);? ? ? ? ? ? }? ? ? ? });//下一頁$(".nextPage").click(function(){if(curPage < totalPages){varpageNo = curPage+1;? ? ? ? ? ? ? ? $(this).attr("href","/emp/getEmpList?pageNo="+pageNo);? ? ? ? ? ? }? ? ? ? });? ? })


最后在主頁面中的員工信息加上一個指定鏈接,跳轉到當前員工信息顯示的頁面(部門操作類似,不再贅述),以及點擊公司LOGO的時候跳轉到主頁面。?

代碼如下:?

head.jsp:

//跳轉到主頁面$("#company_logo").click(function(){$(this).attr("href","/hrms/main");? ? });


leftsidebar.jsp:

//跳轉到員工頁面$(".emp_info").click(function(){$(this).attr("href","/hrms/emp/getEmpList");? ? });//跳轉到部門頁面$(".dept_info").click(function(){$(this).attr("href","/hrms/dept/getDeptList");? ? });


至此,員工信息的顯示部分基本完成。

2 員工添加

接下來將會實現(xiàn)員工的新增操作,以及對新增數(shù)據(jù)的簡單驗證。?

完成的頁面效果如下:?

(點擊圖片查看)

主要完成的需求有:

(1)點擊左側欄的員工新增按鈕,彈出員工新增的模態(tài)框頁面;

(2)對輸入的姓名和郵箱格式進行驗證,格式不正確,提示錯誤信息;

(4) 對輸入的姓名進行姓名是否重復判斷,重復則提示重復信息;

(5)添加成功后跳轉到添加記錄所在的頁面(即最后一頁);

(6)添加失敗則提示錯誤信息。

后臺代碼實現(xiàn)主要有:

/**? ? * 查詢輸入的員工姓名是否重復? ? * @paramempName? ? * @return*/@RequestMapping(value ="/checkEmpExists", method = RequestMethod.GET)@ResponseBodypublicJsonMsgcheckEmpExists(@RequestParam("empName") String empName){//對輸入的姓名與郵箱格式進行驗證String regName ="(^[a-zA-Z0-9-]{3,16}$)|(^[\\u2E80-\\u9FFF]{2,5})";if(!empName.matches(regName)){returnJsonMsg.fail().addInfo("name_reg_error","輸入姓名為2-5位中文或6-16位英文和數(shù)字組合");? ? ? ? }? ? ? ? Employee employee = employeeService.getEmpByName(empName);if(employee !=null){returnJsonMsg.fail().addInfo("name_reg_error","用戶名重復");? ? ? ? }else{returnJsonMsg.success();? ? ? ? }? ? }/**? ? * 新增記錄后,查詢最新的頁數(shù)? ? * @return*/@RequestMapping(value ="/getTotalPages", method = RequestMethod.GET)@ResponseBodypublicJsonMsggetTotalPage(){inttotalItems = employeeService.getEmpCount();//獲取總的頁數(shù)inttemp = totalItems /5;inttotalPages = (totalItems %5==0) ? temp : temp+1;returnJsonMsg.success().addInfo("totalPages", totalPages);? ? }/**? ? * 新增員工? ? * @paramemployee 新增的員工信息? ? * @return*/@RequestMapping(value ="/addEmp", method = RequestMethod.POST)@ResponseBodypublicJsonMsgaddEmp(Employee employee){intres = employeeService.addEmp(employee);if(res ==1){returnJsonMsg.success();? ? ? ? }else{returnJsonMsg.fail();? ? ? ? }? ? }


前端代碼見employeeAdd.jsp。?

主要是jQuey的操作,很多操作可以封裝成一個函數(shù)進行調用,例如錯誤信息的顯示。本文為了便于查看,沒有進行封裝。

3 員工更改

員工修改操作完成頁面如下:?



(點擊圖片查看)

更改主要完成的需求有:

(1) 獲取點擊修改員工的id與name;

(2) 根據(jù)id或name查詢出對應員工信息進行回顯;

(3) 回顯部門列表;

(4) 進行修改,對修改的郵箱格式進行判斷;

(5) 點擊更新按鈕,發(fā)送AJAX請求到后臺進行保存;

(6)更改成功后跳轉到當前更改頁面。

后臺代碼實現(xiàn)主要有:

/**? ? * 更改員工信息? ? * @paramempId? ? * @paramemployee? ? * @return*/@RequestMapping(value ="/updateEmp/{empId}", method = RequestMethod.PUT)@ResponseBodypublicJsonMsgupdateEmp(@PathVariable("empId") Integer empId,? Employee employee){intres = employeeService.updateEmpById(empId, employee);if(res !=1){returnJsonMsg.fail().addInfo("emp_update_error","更改異常");? ? ? ? }returnJsonMsg.success();? ? }


前端頁面+jQuery代碼見:employeeUpdate.jsp

4 員工刪除

員工刪除操作完成頁面如下:?

(點擊圖片查看)

刪除主要完成的需求有:

(1)彈出確認框:是否刪除XX信息;

(2)發(fā)送AJAX請求,執(zhí)行刪除操作;

(3)刪除成功后,跳轉到當前頁。

后臺代碼:

/**? ? * 員工刪除操作? ? * @paramempId? ? * @return*/@RequestMapping(value ="/deleteEmp/{empId}", method = RequestMethod.DELETE)@ResponseBodypublicJsonMsgdeleteEmp(@PathVariable("empId") Integer empId){intres = employeeService.deleteEmpById(empId);if(res !=1){returnJsonMsg.fail().addInfo("emp_del_error","員工刪除異常");? ? ? ? }returnJsonMsg.success();? ? }

前端頁面代碼見employeePage.jsp:

? ? $(".emp_delete_btn").click(function(){varcurPage = ${curPage};vardelEmpId = $(this).parent().parent().find("td:eq(0)").text();vardelEmpName = $(this).parent().parent().find("td:eq(1)").text();if(confirm("確認刪除【"+ delEmpName+"】的信息嗎?")){? ? ? ? ? ? $.ajax({? ? ? ? ? ? ? ? url:"/hrms/emp/deleteEmp/"+delEmpId,? ? ? ? ? ? ? ? type:"DELETE",? ? ? ? ? ? ? ? success:function(result){if(result.code ==100){? ? ? ? ? ? ? ? ? ? ? ? alert("刪除成功!");? ? ? ? ? ? ? ? ? ? ? ? window.location.href="/hrms/emp/getEmpList?pageNo="+curPage;? ? ? ? ? ? ? ? ? ? }else{? ? ? ? ? ? ? ? ? ? ? ? alert(result.extendInfo.emp_del_error);? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? }? ? ? ? ? ? });? ? ? ? }? ? });

至此,SSM項目的增刪改查操作也基本完成,部門操作與上類似,本文不再贅述,感興趣的可以略看Department相關操作的代碼。

5 登錄頁面

最后,為求項目的完整性,加上一個登陸頁面,實現(xiàn)的效果?

圖如下:?

(點擊圖片查看)

后臺主要做了一個簡單的登錄驗證,代碼見LoginController.java:

/**? ? * 登錄:跳轉到登錄頁面? ? * @return*/@RequestMapping(value ="/login", method = RequestMethod.GET)publicStringlogin(){return"login";? ? }/**? ? * 對登錄頁面輸入的用戶名和密碼做簡單的判斷? ? * @paramrequest? ? * @return*/@RequestMapping(value ="/dologin", method = RequestMethod.POST)@ResponseBodypublicJsonMsgdologin(HttpServletRequest request){? ? ? ? String username = request.getParameter("username");? ? ? ? String password = request.getParameter("password");? ? ? ? System.out.println(username + password);if(!"admin1234".equals(username + password)){returnJsonMsg.fail().addInfo("login_error","輸入賬號用戶名與密碼不匹配,請重新輸入!");? ? ? ? }returnJsonMsg.success();? ? }/**? ? * 跳轉到主頁面? ? * @return*/@RequestMapping(value ="/main", method = RequestMethod.GET)publicStringmain(){return"main";? ? }/**? ? * 退出登錄:從主頁面跳轉到登錄頁面? ? * @return*/@RequestMapping(value ="/logout", method = RequestMethod.GET)publicStringlogout(){return"login";? ? }


前臺頁面見login.jsp代碼;以及退出登錄按鈕的操作見head.jsp:

//賬號退出$(".hrms_logout").click(function(){window.location.href ="/hrms/logout";});


五、項目代碼下載

最后,將本次項目的代碼上傳到我的github當中,想要下載項目源碼的話:戳這里。?

如果覺得對你有幫助別忘了在我的github上隨手點個star,THX!

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容