目錄
- 前言
- 增删改操作(Rest風格)
- 1 實作分頁功能
-
- 1. 1 配置檔案操作步驟
-
- ①導入依賴
- ②配置
- ③PageHelper 非侵入式的展現
- 1.2 案例實作
-
- ① 首頁超連結
- ② handler方法
- ③ Service及實作類
- ④ mapper及mapper.xml配置檔案
- ⑤ 頁面展示(emp-page.html)
-
- 1)顯示資料
- ⑥為什麼是PageInfo而不是Page
-
- 1)List接口的具體實作
- 2)提出問題
- 2 實作删除功能
-
- 2.1 編寫删除超連結并綁定點選事件
- 2.2 編寫通用表單
- 2.3 編寫單擊響應函數
- 2.4 mapper方法
- 2.5 mapper.xml
- 2.6 service和serviceImpl
- 2.7 handler方法
- 3 前往表單頁面(emp-add.html)
-
- 3.1 編寫超連結
- 3.2 在spring-mvc.xml配置view-controller
- 3.3 建立視圖模闆頁面
- 4 儲存表單
-
- 4.1 mapper
- 4.2 mapper.xml配置檔案
- 4.3 service和實作類
- 4.4 handler方法
- 5 更新:表單回顯(其實就是查詢你點選要更新的資料,顯示在頁面上)
-
- 5.1 編寫超連接配接
- 5.2 mapper接口
- 5.3 mapper配置檔案
- 5.4 service及實作類
- 5.5 handler
- 5.6 編輯emp-edit.html
- 6 送出表單
- 6.1 mapper接口方法
- 6.2 mapper配置檔案
- 6.3 service及serviceImpl方法
- 6.4 handler方法
前言
感謝尚矽谷提供的免費的課程資源,讓我們一起進入ssm整合的課程學習中吧。
增删改操作(Rest風格)
功能 | 位址 | 請求方式 |
---|---|---|
删除 | /emp/{empId}/{pageNo} | DELETE |
前往新增頁面 | /emp/add | view-controller |
送出新增表單 | /emp | POST |
前往更新頁面 | /emp/{empId}/{pageNo} | GET |
送出更新表單 | /emp | PUT |
1 實作分頁功能
我們可以利用mybatis中的分頁插件功能來實作快速分頁。
1. 1 配置檔案操作步驟
①導入依賴
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
②配置
<!-- 配置 SqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
……
<!-- 在 plugins 屬性中配置 Mybatis 插件 -->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<props>
<!-- 設定 reasonable 為 true 表示将頁碼進行合理化修正。頁碼的有效範圍:1~總頁數 -->
<prop key="reasonable">true</prop>
<!-- 資料庫方言:同樣都是 SQL 語句,拿到不同資料庫中,在文法上會有差異 -->
<!-- 預設情況下,按照 MySQL 作為資料庫方言來運作 -->
<prop key="helperDialect">mysql</prop>
</props>
</property>
</bean>
</array>
</property>
</bean>
③PageHelper 非侵入式的展現
PageHelper.startPage(pageNo, pageSize);
開啟分頁功能,就在 SQL 語句後面附加 LIMIT 子句并查詢總記錄數;不開啟就還是按照原樣查詢。分頁功能對原有的 Mapper 接口、SQL 語句沒有任何影響。這個效果可以稱之為是非侵入式,也可以說是可插拔的。
1.2 案例實作
① 首頁超連結
② handler方法
使用 @PathVariable 注解修飾一個形參,SpringMVC 就會将比對到的值從形參這裡傳
@RequestMapping("/get/page/{pageNo}")
public String getPage(
@PathVariable("pageNo") Integer pageNo,
Model model) {
// PageInfo 對象封裝了和分頁相關的所有資訊
PageInfo<Emp> pageInfo = empService.getPageInfo(pageNo);
// 将 PageInfo 對象存入模型
model.addAttribute("pageInfo", pageInfo);
return "emp-page";
}
③ Service及實作類
@Override
public PageInfo<Emp> getPageInfo(Integer pageNo) {
// 1、确定每頁顯示資料的條數
int pageSize = 5;
// 2、設定分頁資料:開啟分頁功能。開啟後,後面執行的 SELECT 語句會自動被附加 LIMIT 子句,
// 而且會自動查詢總記錄數
PageHelper.startPage(pageNo, pageSize);
// 3、正常執行查詢
List<Emp> empList = empMapper.selectAll();
// 4、封裝為 PageInfo 對象傳回
return new PageInfo<>(empList);
}
④ mapper及mapper.xml配置檔案
<!-- List<Emp> selectAll();-->
<select id="selectAll" resultType="Emp">
select emp_id,emp_name,emp_salary from t_emp
</select>
⑤ 頁面展示(emp-page.html)
1)顯示資料
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
table{
border-collapse: collapse;
margin: 0px auto 0px auto;
}
table th,td {
border: 1px solid black;
text-align: center;
}
</style>
</head>
<body>
<table>
<tr>
<th>ID</th>
<th>NAME</th>
<th>SALARY</th>
</tr>
<tbody th:if="${#lists.isEmpty(pageInfo.list)}">
<tr>
<td colspan="3">抱歉,沒有查詢到資料!</td>
</tr>
</tbody>
<tbody th:if="${not #lists.isEmpty(pageInfo.list)}">
<tr th:each="emp : ${pageInfo.list}">
<td th:text="${emp.empId}">這裡顯示員工ID</td>
<td th:text="${emp.empName}">這裡顯示員工Name</td>
<td th:text="${emp.empSalary}">這裡顯示員工Salary</td>
</tr>
<tr>
<td colspan="3">
<!-- 判斷是否是上一頁-->
<span th:if="${pageInfo.hasPreviousPage}">
<a th:href="@{/get/page/1}">首頁</a>
<!-- 不能是@{/get/page/prePage},如果這樣寫就變成路徑了。-->
<a th:href="@{/get/page/}+${pageInfo.prePage}">上一頁</a>
</span>
<!-- 判斷是否是目前頁,如果不是,則顯示超連結-->
<span th:each="navigator:${pageInfo.navigatepageNums}">
<a th:if="${navigator != pageInfo.pageNum}"
th:href="@{/get/page/}+${navigator}"
th:text="'['+${navigator}+']'"></a>
<!--判斷是否是目前頁,如果是,則顯示頁碼-->
<span th:if="${navigator==pageInfo.pageNum}"
th:text="'['+${navigator}+']'"></span>
</span>
<span th:if="${pageInfo.hasNextPage}">
<a th:href="@{/get/page/}+${pageInfo.nextPage}">下一頁</a>
<a th:href="@{/get/page/}+${pageInfo.pages}">最後一頁</a>
</span>
<span th:text="${pageInfo.pageNum} + '/' +${pageInfo.pages}"></span>
</td>
</tr>
</tbody>
</table>
<a th:href="@{/}">首頁</a>
</body>
</html>
⑥為什麼是PageInfo而不是Page
1)List接口的具體實作
當我們開啟了分頁功能後,查詢一個 List 集合,實際傳回的是:com.github.pagehelper.Page 類型。這個 Page 類繼承了 ArrayList,是以也相容 List 接口類型。
2)提出問題
如果我們将 Page 類型的對象存入模型,轉發到視圖模闆上顯示資料,會存在一個問題:視圖模闆技術隻承認這個對象是一個 List 集合,不識别 List 集合之外的其它屬性。
這一點在其他場合也需要注意:我們開發時盡量不要繼承 ArrayList、HashMap 等類似的集合實作類。如果繼承了,那麼頁面視圖模闆技術或其他表達式往往隻能識别我們的對象是一個集合,而無法通路額外封裝的其他屬性。
是以 Page 對象需要封裝為 PageInfo,讓 list、pageNum 等等資料作為 PageInfo 對象的屬性;PageInfo 本身并不是一個 List 類型的集合。
2 實作删除功能
在emp-page.html頁面
2.1 編寫删除超連結并綁定點選事件
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLzMWM1cTM3EjNmdTZ2kjNhRWOhRDZmNTOxIDO1UjYyYzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
我們最終要實作的被解析出來的超連結是
/emp/{empId}/{pageNo}
.
onclick="convertMethod(this)"
表示點選這個超連結時,調用 convertMethod() 函數
- this 代表目前超連結對象
- event 是代表目前事件的事件對象
請求用@{},取值用${}
2.2 編寫通用表單
思路:
超連結 ----GET請求
表單-------POST請求
先借助表單将超連接配接的GET請求轉換為POST請求,然後使用rest文法将DELETE請求。
<!--元件名稱:通用表單-->
<!--作用:将删除超連結的GET請求轉換為POST,并攜帶_method請求參數-->
<form id="covertFrom" method="post">
<!-- 請求參數作用:告訴伺服器端 hiddenHttpMethodFilter 要轉換的目标請求方式 -->
<!-- 請求參數名:_method,這是 hiddenHttpMethodFilter 中規定的 -->
<!-- 請求參數值:delete,這是因為我們希望伺服器端将請求方式最終轉換為 delete -->
<input type="hidden" name="_method" value="delete"/>
</form>
2.3 編寫單擊響應函數
<!--編輯點選響應函數-->
<script type="text/javascript">
function convertMethod(anchorElement,event) {
// 擷取超連結原本要通路的目标位址
var targetURL = anchorElement.href;
// 擷取表單對象
var formEle = document.getElementById("covertFrom");
// 把超連結原本要通路的位址設定給表單的 action 屬性
formEle.action = targetURL;
// 送出表單
formEle.submit();
// 取消控件的預設行為:讓超連結不會跳轉
event.preventDefault();
}
</script>
2.4 mapper方法
2.5 mapper.xml
<!-- void deleteByPrimaryKey(Integer empId);-->
<delete id="deleteByPrimaryKey" >
delete from t_emp where emp_id=#{empId}
</delete>
2.6 service和serviceImpl
service
serviceImpl
//propagation:事務傳播機制--不管是否存在事務,
//都建立一個新的事務,原來的挂起,新的執行完畢,繼續執行老的事務
//rollbackFor:用來指明復原的條件是哪些異常類或者異常類名。
@Transactional(
propagation = Propagation.REQUIRES_NEW,
rollbackFor = Exception.class
)
@Override
public void doRemove(Integer empId) {
empMapper.deleteByPrimaryKey(empId);
}
2.7 handler方法
@RequestMapping(value="/emp/{empId}/{pageNo}",method = RequestMethod.DELETE)
public String doRemove(
@PathVariable("empId")Integer empId,
@PathVariable("pageNo")Integer pageNo
){
empService.doRemove(empId);
return "redirect:/get/page/" + pageNo;
}
3 前往表單頁面(emp-add.html)
3.1 編寫超連結
我們建立一個跳轉頁面,當點選添加資料的時候就跳轉到emp.add.html頁面。
3.2 在spring-mvc.xml配置view-controller
3.3 建立視圖模闆頁面
action屬性規定當送出表單時,向何處發送表單資料
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>添加資料</title>
</head>
<body>
<form th:action="@{/emp}" method="post">
姓名:<input type="text" name="empName"/><br/>
工資:<input type="text" name="empSalary"/><br/>
<button type="submit">儲存</button>
</form>
</body>
</html>
4 儲存表單
4.1 mapper
4.2 mapper.xml配置檔案
<!-- void insert(Emp emp);-->
<insert id="insert" >
<!--寫法1-->
<!--insert into t_emp(emp_name,emp_salary) values(#{empName},#{empSalary})-->
<!--寫法2-->
insert into t_emp values(null,#{empName},#{empSalary})
</insert>
4.3 service和實作類
service
serviceImpl
@Transactional(
propagation = Propagation.REQUIRES_NEW,
rollbackFor = Exception.class
)
@Override
public void save(Emp emp) {
empMapper.insert(emp);
}
4.4 handler方法
注意:
此處擷取參數我們使用的是實體類,這個要求參數和資料庫中的表要一樣,屬性對應。
@RequestMapping(value="/emp",method = RequestMethod.POST)
public String doSave(
//使用實體類接收發送過來的請求參數
Emp emp ){
empService.save(emp);
//跳轉到最後一頁,Integer.MAX_VALUE---為了確定直接前往最後一頁
return "redirect:/get/page/"+Integer.MAX_VALUE;
}
5 更新:表單回顯(其實就是查詢你點選要更新的資料,顯示在頁面上)
5.1 編寫超連接配接
<td>
<a th:href="@{/emp/}+${emp.empId}+'/'+${pageInfo.pageNum}">更新</a>
</td>
5.2 mapper接口
5.3 mapper配置檔案
<!-- Emp selectByPrimaryKey(Integer empId);-->
<select id="selectByPrimaryKey" resultType="emp">
select emp_id,emp_name,emp_salary from t_emp where emp_id = #{empId}
</select>
5.4 service及實作類
serviceImpl
@Override
public Emp getEmpById(Integer empId) {
return empMapper.selectByPrimaryKey(empId);
}
service
5.5 handler
@RequestMapping(value="/emp/{empId}/{pageNo}",method = RequestMethod.GET)
public String doFormResisPlayer(
@PathVariable("empId") Integer empId,
@PathVariable("pageNo") Integer pageNo,
Model model
){
Emp emp = empService.getEmpById(empId);
//将實體類對象存入模型
model.addAttribute("emp",emp);
return "emp-edit";
}
為什麼要用Model模型,是因為我們要将查詢到的資料存入模型中。
傳回到更新頁面,意味着我們要建立一個emp-edit.html頁面。
5.6 編輯emp-edit.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>更新</title>
</head>
<body>
<form th:action="@{/emp}" method="post">
<input type="hidden" name="_method" value="put"/>
<input type="hidden" name="empId" th:value="${emp.empId}"/>
<input type="hidden" name="pageNo" th:value="${pageNo}"/>
姓名:<input type="text" name="empName" th:value="${emp.empName}"/><br/>
工資:<input type="text" name="empSalary" th:value="${emp.empSalary}"/><br/>
<button type="submit">更新</button>
</form>
</body>
</html>
6 送出表單
6.1 mapper接口方法
6.2 mapper配置檔案
<!-- void updateByPrimaryKey(Emp emp);-->
<update id="updateByPrimaryKey">
update t_emp set emp_name=#{empName},emp_salary=#{empSalary}
where emp_id = #{empId}
</update>
6.3 service及serviceImpl方法
@Transactional(
propagation = Propagation.REQUIRES_NEW,
rollbackFor = Exception.class
)
@Override
public void doUpdate(Emp emp) {
empMapper.updateByPrimaryKey(emp);
}
6.4 handler方法
@RequestMapping(value = "/emp",method = RequestMethod.PUT)
public String doUpdate(
Emp emp,
@PathVariable("pageNo") Integer pageNo
){
empService.doUpdate(emp);
return "redirect:/get/page"+pageNo;
}