轉載自:Guassic(一個致力於AI卻不得不兼顧項目的研究生)
七、用戶管理
既然我們要做一個博客管理系統,當然要首先實現我們的用戶管理。在上一文中,我們已經配置好了數據庫。接下來,就要實現網站的一些業務邏輯。
1、JPA操作定義
在實現用戶管理操作之前,需要講解一下JPA的開發工作。
首先,在com.gaussic.repository包內新建一個UserRepository接口:
讓該接口繼承 JpaRepository:
1
2
3
4
5
6
7
8
9
10
11
12
|
package com.gaussic.repository; import com.gaussic.model.UserEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; /** * Created by dzkan on 2016/3/8. */ @Repository public interface UserRepository extends JpaRepository<UserEntity, Integer> { } |
在JpaRepository中,定義了幾個簡化的操作數據庫的方法:
(1) findAll():查找表中所有記錄;
(2)findOne(Integer id):按id來查找某一條記錄;
(3)findByXXX(Object xxx):在這裏XXX是一個字段名,根據該字段的值開查找所有記錄;
(4)save()和delete():添加一條記錄以及刪除一條記錄。
除此之外,我們還可以在該repository中自定義新的方法,這將在稍後實際開發中提及。
2、後臺管理
爲了儘可能的在省去篇幅的情況下,在此省去管理員操作的開發。默認在訪問 /admin 時,進入後臺管理。
(1)查看所有用戶
將MainController補充爲如下形式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
package com.gaussic.controller; import com.gaussic.model.UserEntity; import com.gaussic.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import java.util.List; /** * Created by dzkan on 2016/3/8. */ @Controller public class MainController { // 自動裝配數據庫接口,不需要再寫原始的Connection來操作數據庫 @Autowired UserRepository userRepository; @RequestMapping (value = "/" , method = RequestMethod.GET) public String index() { return "index" ; } @RequestMapping (value = "/admin/users" , method = RequestMethod.GET) public String getUsers(ModelMap modelMap) { // 查詢user表中所有記錄 List<UserEntity> userList = userRepository.findAll(); // 將所有記錄傳遞給要返回的jsp頁面,放在userList當中 modelMap.addAttribute( "userList" , userList); // 返回pages目錄下的admin/users.jsp頁面 return "admin/users" ; } } |
講解:
-
自動裝配:相當於數據庫操作的極簡化,只要定義了就可以直接進行數據庫操作,不用再去管開啓連接、關閉連接等問題
-
找到所有記錄:使用JpaRepository的默認方法findAll()。
-
modelMap:用於將controller方法裏面的參數傳遞給所需的jsp頁面,以進行相關顯示。
現在,需要在pages下新建目錄admin,並新建users.jsp頁面,以進行用戶的管理:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <! DOCTYPE html> < html lang = "zh-CN" > < head > < meta charset = "utf-8" > < meta http-equiv = "X-UA-Compatible" content = "IE=edge" > < meta name = "viewport" content = "width=device-width, initial-scale=1" > <!-- 上述3個meta標籤*必須*放在最前面,任何其他內容都*必須*跟隨其後! --> < title >SpringMVC 用戶管理</ title > <!-- 新 Bootstrap 核心 CSS 文件 --> < link rel = "stylesheet" href = "//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css" > <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!--[if lt IE 9]> <script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script> <![endif]--> </ head > < body > < div class = "container" > < h1 >SpringMVC 博客系統-用戶管理</ h1 > < hr /> < h3 >所有用戶 < a href = "/admin/users/add" type = "button" class = "btn btn-primary btn-sm" >添加</ a ></ h3 > <!-- 如果用戶列表爲空 --> < c:if test = "${empty userList}" > < div class = "alert alert-warning" role = "alert" > < span class = "glyphicon glyphicon-info-sign" aria-hidden = "true" ></ span >User表爲空,請< a href = "/admin/users/add" type = "button" class = "btn btn-primary btn-sm" >添加</ a > </ div > </ c:if > <!-- 如果用戶列表非空 --> < c:if test = "${!empty userList}" > < table class = "table table-bordered table-striped" > < tr > < th >ID</ th > < th >暱稱</ th > < th >姓名</ th > < th >密碼</ th > < th >操作</ th > </ tr > < c:forEach items = "${userList}" var = "user" > < tr > < td >${user.id}</ td > < td >${user.nickname}</ td > < td >${user.firstName} ${user.lastName}</ td > < td >${user.password}</ td > < td > < a href = "/admin/users/show/${user.id}" type = "button" class = "btn btn-sm btn-success" >詳情</ a > < a href = "/admin/users/update/${user.id}" type = "button" class = "btn btn-sm btn-warning" >修改</ a > < a href = "/admin/users/delete/${user.id}" type = "button" class = "btn btn-sm btn-danger" >刪除</ a > </ td > </ tr > </ c:forEach > </ table > </ c:if > </ div > <!-- jQuery文件。務必在bootstrap.min.js 之前引入 --> < script src = "//cdn.bootcss.com/jquery/1.11.3/jquery.min.js" ></ script > <!-- 最新的 Bootstrap 核心 JavaScript 文件 --> < script src = "//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js" ></ script > </ body > </ html > |
講解:
-
<c>標籤:在jsp中使用了jstl語法,可以方便地進行一些判斷<c:if>與遍歷操作<c:forEach>;
-
頁面使用了Bootstrap,部分功能將在之後實現。
運行Tomcat,在瀏覽器中輸入 http://localhost:8080/admin/users,進入用戶管理界面,顯示如下:
由於目前數據庫中沒有數據,因而顯示爲空,現在需要向數據庫中添加用戶。
(2)添加用戶
在MainController中增加兩個方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
// get請求,訪問添加用戶 頁面 @RequestMapping (value = "/admin/users/add" , method = RequestMethod.GET) public String addUser() { // 轉到 admin/addUser.jsp頁面 return "admin/addUser" ; } // post請求,處理添加用戶請求,並重定向到用戶管理頁面 @RequestMapping (value = "/admin/users/addP" , method = RequestMethod.POST) public String addUserPost( @ModelAttribute ( "user" ) UserEntity userEntity) { // 注意此處,post請求傳遞過來的是一個UserEntity對象,裏面包含了該用戶的信息 // 通過@ModelAttribute()註解可以獲取傳遞過來的'user',並創建這個對象 // 數據庫中添加一個用戶,該步暫時不會刷新緩存 //userRepository.save(userEntity); // 數據庫中添加一個用戶,並立即刷新緩存 userRepository.saveAndFlush(userEntity); // 重定向到用戶管理頁面,方法爲 redirect:url return "redirect:/admin/users" ; } |
講解:
-
/admin/users/add請求:get請求轉到添加用戶頁面
-
/admin/users/addP請求:post請求收集數據並存庫
-
@ModelAttribute註解:收集post過來的數據(在此,相當於post過來了一整個userEntity,不用一個一個地取)
-
save()和saveAndFlush():save()方法處理完畢後,數據依然在緩衝區未寫入數據庫,使用saveAndFlush()可以立即刷新緩衝區,寫入數據庫
-
redirect:/admin/users:這裏使用重定向,可以讓該方法重定向訪問一個請求,ruturn之後,將跳轉到 :/admin/users 所訪問的頁面。
現在,在pages目錄下新建一個addUser.jsp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <! DOCTYPE html> < html lang = "zh-CN" > < head > < meta charset = "utf-8" > < meta http-equiv = "X-UA-Compatible" content = "IE=edge" > < meta name = "viewport" content = "width=device-width, initial-scale=1" > <!-- 上述3個meta標籤*必須*放在最前面,任何其他內容都*必須*跟隨其後! --> < title >SpringMVC 添加用戶</ title > <!-- 新 Bootstrap 核心 CSS 文件 --> < link rel = "stylesheet" href = "//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css" > <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!--[if lt IE 9]> <script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script> <![endif]--> </ head > < body > < div class = "container" > < h1 >SpringMVC 添加用戶</ h1 > < hr /> < form:form action = "/admin/users/addP" method = "post" commandName = "user" role = "form" > < div class = "form-group" > < label for = "firstName" >Nickname:</ label > < input type = "text" class = "form-control" id = "nickname" name = "nickname" placeholder = "Enter Nickname:" /> </ div > < div class = "form-group" > < label for = "firstName" >First Name:</ label > < input type = "text" class = "form-control" id = "firstName" name = "firstName" placeholder = "Enter FirstName:" /> </ div > < div class = "form-group" > < label for = "lastName" >Last Name:</ label > < input type = "text" class = "form-control" id = "lastName" name = "lastName" placeholder = "Enter LastName:" /> </ div > < div class = "form-group" > < label for = "password" >Password:</ label > < input type = "text" class = "form-control" id = "password" name = "password" placeholder = "Enter Password:" /> </ div > < div class = "form-group" > < button type = "submit" class = "btn btn-sm btn-success" >提交</ button > </ div > </ form:form > </ div > <!-- jQuery文件。務必在bootstrap.min.js 之前引入 --> < script src = "//cdn.bootcss.com/jquery/1.11.3/jquery.min.js" ></ script > <!-- 最新的 Bootstrap 核心 JavaScript 文件 --> < script src = "//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js" ></ script > </ body > </ html > |
講解:
-
<form:form>標籤:使用Spring的form標籤,可以方便的收集整塊數據,commondName=“user”說明form內的內容都保存在這個user實例中,然後將整個user實例傳遞給controller處理。在所有的input標籤中,name一定要與UserEntity中的成員相同,不然無法找到。
-
在提交之後,後臺將會處理 /admin/users/addP 請求。
現在,重新啓動服務器,訪問 http://localhost:8080/admin/users/add 頁面,如下圖所示:
輸入數據,點擊提交,數據庫中將會寫入新的用戶,重新跳轉到用戶管理頁面:
(3)查看用戶詳情
在MainController中加入查看詳情操作:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
// 查看用戶詳情 // @PathVariable可以收集url中的變量,需匹配的變量用{}括起來 // 例如:訪問 localhost:8080/admin/users/show/1 ,將匹配 id = 1 @RequestMapping (value = "/admin/users/show/{id}" , method = RequestMethod.GET) public String showUser( @PathVariable ( "id" ) Integer userId, ModelMap modelMap) { // 找到userId所表示的用戶 UserEntity userEntity = userRepository.findOne(userId); // 傳遞給請求頁面 modelMap.addAttribute( "user" , userEntity); return "admin/userDetail" ; } |
在pages目錄下新建 userDetail.jsp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <! DOCTYPE html> < html lang = "zh-CN" > < head > < meta charset = "utf-8" > < meta http-equiv = "X-UA-Compatible" content = "IE=edge" > < meta name = "viewport" content = "width=device-width, initial-scale=1" > <!-- 上述3個meta標籤*必須*放在最前面,任何其他內容都*必須*跟隨其後! --> < title >SpringMVC 用戶詳情</ title > <!-- 新 Bootstrap 核心 CSS 文件 --> < link rel = "stylesheet" href = "//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css" > <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!--[if lt IE 9]> <script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script> <![endif]--> </ head > < body > < div class = "container" > < h1 >SpringMVC 用戶詳情</ h1 > < hr /> < table class = "table table-bordered table-striped" > < tr > < th >ID</ th > < td >${user.id}</ td > </ tr > < tr > < th >Nickname</ th > < td >${user.nickname}</ td > </ tr > < tr > < th >First Name</ th > < td >${user.firstName}</ td > </ tr > < tr > < th >Last Name</ th > < td >${user.lastName}</ td > </ tr > < tr > < th >Password</ th > < td >${user.password}</ td > </ tr > </ table > </ div > <!-- jQuery文件。務必在bootstrap.min.js 之前引入 --> < script src = "//cdn.bootcss.com/jquery/1.11.3/jquery.min.js" ></ script > <!-- 最新的 Bootstrap 核心 JavaScript 文件 --> < script src = "//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js" ></ script > </ body > </ html > |
講解:如何訪問一個實例內的數據?
使用${}語法,在{}內可以使用類似Java的方法方便地訪問數據。
重啓服務器,進入 http://localhost:8080/admin/users ,點擊ID = 1的用戶的 詳情 按鈕,可以查看用戶詳情:
從url可以看出,訪問的是ID=1的用戶的詳細情況,這樣的URL採用了REST風格設計,看起來更加簡便。
(4)修改用戶信息
現在我們要對用戶信息做一定的修改,那該如何做呢。假設我們要能夠修改全部的數據(除了id),JpaRepository未定義update方法,需要我們自己定義。
打開UserRepository,添加updateUser()接口方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
package com.gaussic.repository; import com.gaussic.model.UserEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; /** * Created by dzkan on 2016/3/8. */ @Repository public interface UserRepository extends JpaRepository<UserEntity, Integer> { @Modifying // 說明該方法是修改操作 @Transactional // 說明該方法是事務性操作 // 定義查詢 // @Param註解用於提取參數 @Query ( "update UserEntity us set us.nickname=:qNickname, us.firstName=:qFirstName, us.lastName=:qLastName, us.password=:qPassword where us.id=:qId" ) public void updateUser( @Param ( "qNickname" ) String nickname, @Param ( "qFirstName" ) String firstName, @Param ( "qLastName" ) String qLastName, @Param ( "qPassword" ) String password, @Param ( "qId" ) Integer id); } |
在MainController中定義update操作方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
// 更新用戶信息 頁面 @RequestMapping (value = "/admin/users/update/{id}" , method = RequestMethod.GET) public String updateUser( @PathVariable ( "id" ) Integer userId, ModelMap modelMap) { // 找到userId所表示的用戶 UserEntity userEntity = userRepository.findOne(userId); // 傳遞給請求頁面 modelMap.addAttribute( "user" , userEntity); return "admin/updateUser" ; } // 更新用戶信息 操作 @RequestMapping (value = "/admin/users/updateP" , method = RequestMethod.POST) public String updateUserPost( @ModelAttribute ( "user" ) UserEntity user) { // 更新用戶信息 userRepository.updateUser(user.getNickname(), user.getFirstName(), user.getLastName(), user.getPassword(), user.getId()); userRepository.flush(); // 刷新緩衝區 return "redirect:/admin/users" ; } |
然後,在pages目錄下,新建updateUser.jsp文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <! DOCTYPE html> < html lang = "zh-CN" > < head > < meta charset = "utf-8" > < meta http-equiv = "X-UA-Compatible" content = "IE=edge" > < meta name = "viewport" content = "width=device-width, initial-scale=1" > <!-- 上述3個meta標籤*必須*放在最前面,任何其他內容都*必須*跟隨其後! --> < title >SpringMVC Demo 更新用戶</ title > <!-- 新 Bootstrap 核心 CSS 文件 --> < link rel = "stylesheet" href = "//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css" > <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!--[if lt IE 9]> <script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script> <![endif]--> </ head > < body > < div class = "container" > < h1 >SpringMVC 更新用戶信息</ h1 > < hr /> < form:form action = "/admin/users/updateP" method = "post" commandName = "userP" role = "form" > < div class = "form-group" > < label for = "firstName" >Nickname:</ label > < input type = "text" class = "form-control" id = "nickname" name = "nickname" placeholder = "Enter Nickname:" value = "${user.nickname}" /> </ div > < div class = "form-group" > < label for = "firstName" >First Name:</ label > < input type = "text" class = "form-control" id = "firstName" name = "firstName" placeholder = "Enter FirstName:" value = "${user.firstName}" /> </ div > < div class = "form-group" > < label for = "lastName" >Last Name:</ label > < input type = "text" class = "form-control" id = "lastName" name = "lastName" placeholder = "Enter LastName:" value = "${user.lastName}" /> </ div > < div class = "form-group" > < label for = "password" >Password:</ label > < input type = "text" class = "form-control" id = "password" name = "password" placeholder = "Enter Password:" value = "${user.password}" /> </ div > <!-- 把 id 一併寫入 userP 中 --> < input type = "hidden" id = "id" name = "id" value = "${user.id}" /> < div class = "form-group" > < button type = "submit" class = "btn btn-sm btn-success" >提交</ button > </ div > </ form:form > </ div > <!-- jQuery文件。務必在bootstrap.min.js 之前引入 --> < script src = "//cdn.bootcss.com/jquery/1.11.3/jquery.min.js" ></ script > <!-- 最新的 Bootstrap 核心 JavaScript 文件 --> < script src = "//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js" ></ script > </ body > </ html > |
重啓服務器,進入 http://localhost:8080/admin/users ,點擊第一個用戶的 修改 按鈕,做如下修改:
提交後,重新跳轉回用戶管理頁面,可發現修改完成:
(5)刪除用戶
現在,新添加一個用戶:
現在我們需要刪掉新加入的用戶,打開MainController,加入以下方法:
1
2
3
4
5
6
7
8
9
10
|
// 刪除用戶 @RequestMapping (value = "/admin/users/delete/{id}" , method = RequestMethod.GET) public String deleteUser( @PathVariable ( "id" ) Integer userId) { // 刪除id爲userId的用戶 userRepository.delete(userId); // 立即刷新 userRepository.flush(); return "redirect:/admin/users" ; } |
重啓服務器,進入 http://localhost:8080/admin/users ,點擊ID=2的用戶的刪除按鈕,在controller中處理完之後,將跳轉回用戶管理界面:
這樣,增刪該查基本完成了。
其實,更到這裏,基本就可以開始開發工作了,還有一些其他的功能,都需要通過平時的積累以及多查資料來完成。例如JSON數據的處理,異步請求的處理,以及相關外鍵等操作。