博客地址:ONESTARの客棧
源碼領取方式一:
- 掃一掃文末二維碼,關注公衆號【編程日刊】,後臺回覆【博客】,即可領取源碼
源碼領取方式二:
以jpa爲持久層源碼地址:https://github.com/oneStarLR/myblog-jpa
以mybatis爲持久層源碼地址:https://github.com/oneStarLR/myblog-mybaits
歡迎給star以鼓勵(^_−)☆
本文將從MVC架構,分類的新增、編輯修改、刪除來講述SpringBoot搭建個人博客的分類管理
1.持久層接口
正常情況下自己寫代碼的時候是一個一個功能來完成,爲了方便書寫,這裏就將分類管理中所有功能一次列出來。
分析:
問:持久層需要哪些接口?
答:分類管理有查詢分類、保存分類、修改編輯分類、刪除分類、因此需要有getAllType、saveType、updateType、deleteType接口
問:分類可是會涉及到多表查詢的,光這些接口夠了嗎?編輯修改分類的時候如何判斷是修改的哪個分類?跳轉修改頁面時如何將要修改的參數獲取到前端頁面?分類頁面顯示的時候需要顯示博客信息,要如何將博客和分類一起顯示出來?這些都是需要解決的問題,不過這裏只解決分類管理的問題,多表問題後面遇到了再來解決。
答:根據功能來看,光以上接口肯定是不夠的,還要有:
- getTypeByName():修改分類時根據分類名稱來查詢分類
- getType():跳轉修改分類頁面時根據id查詢分類
在dao包下創建TypeDao分類持久層接口,代碼如下
package com.star.dao; import com.star.entity.Type; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; import java.util.List; /** * @Description: 分類持久層接口 * @Date: Created in 20:21 2020/6/1 * @Author: ONESTAR * @QQ羣: 530311074 * @URL: https://onestar.newstar.net.cn/ */ @Mapper @Repository public interface TypeDao { //新增保存分類 int saveType(Type type); //根據id查詢分類 Type getType(Long id); //查詢所有分類 List<Type> getAllType(); //根據分類名稱查詢分類 Type getTypeByName(String name); //編輯修改分類 int updateType(Type type); //刪除分類 void deleteType(Long id); }
2.分類管理mapper
分析:
問:分類的mapper裏面需要哪些SQL?
答:根據需求來:增、刪、改、查,根據持久層的接口,查詢需要有根據id查詢分類、查詢所有分類、根據分類名稱查詢分類
在mapper文件夾下創建TypeDao.xml文件,編寫SQL,如下:
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.star.dao.TypeDao"> <!--新增保存分類--> <insert id="saveType" parameterType="com.star.entity.Type"> insert into myblog.t_type values (#{id},#{name}); </insert> <!--根據id查詢分類--> <select id="getType" resultType="com.star.entity.Type"> select id,name from myblog.t_type where id = #{id} </select> <!--查詢所有分類--> <select id="getAllType" resultType="com.star.entity.Type"> select * from myblog.t_type </select> <!--根據分類名稱來查詢--> <select id="getTypeByName" resultType="com.star.entity.Type"> select * from myblog.t_type where name = #{name} </select> <!--編輯修改分類--> <update id="updateType" parameterType="com.star.entity.Type"> update myblog.t_type set name = #{name} where id = #{id} </update> <!--刪除分類--> <delete id="deleteType" > delete from myblog.t_type where id = #{id} </delete> </mapper>
講解:
parameterType屬性:用於指定傳入參數的類型,傳入的是一個類的對象,所以寫全類名
resultType屬性:用於指定結果集的類型
#{ } 字符:代表佔位符,類似 jdbc 中的 ?,用於執行語句時替換實際的數據
3.分類管理業務層
分類業務層接口
這裏和持久層接口是一樣的,就不做分析,在service包下創建TypeService接口,代碼如下:
package com.star.service; import com.star.entity.Type; import java.util.List; /** * @Description: 分類業務層接口 * @Date: Created in 11:41 2020/6/2 * @Author: ONESTAR * @QQ羣: 530311074 * @URL: https://onestar.newstar.net.cn/ */ public interface TypeService { //新增保存分類 int saveType(Type type); //根據id查詢分類 Type getType(Long id); //查詢所有分類 List<Type> getAllType(); //根據分類名稱查詢分類 Type getTypeByName(String name); //編輯修改分類 int updateType(Type type); //刪除分類 void deleteType(Long id); }
接口實現類
沒啥好分析的,直接調用持久層接口,在Impl包下創建TypeServiceImpl類實現TypeService接口,代碼如下:
package com.star.service.Impl; import com.star.dao.TypeDao; import com.star.entity.Type; import com.star.service.TypeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; /** * @Description: 分類業務層接口實現類 * @Date: Created in 13:32 2020/6/2 * @Author: ONESTAR * @QQ羣: 530311074 * @URL: https://onestar.newstar.net.cn/ */ @Service public class TypeServiceImpl implements TypeService { @Autowired private TypeDao typeDao; @Transactional @Override public int saveType(Type type) { return typeDao.saveType(type); } @Transactional @Override public Type getType(Long id) { return typeDao.getType(id); } @Transactional @Override public List<Type> getAllType() { return typeDao.getAllType(); } @Override public Type getTypeByName(String name) { return typeDao.getTypeByName(name); } @Transactional @Override public int updateType(Type type) { return typeDao.updateType(type); } @Transactional @Override public void deleteType(Long id) { typeDao.deleteType(id); } }
講解:
@Service註解:用於標註業務層組件
@Autowired註解:@Autowired表示被修飾的類需要注入對象,spring會掃描所有被@Autowired標註的類,然後根據類型在ioc容器中找到匹配的類注入
@Transactional註解:實現事務操作
4.分類管理控制器
分析:
問:分類管理控制器需要考慮哪些功能?
答:基本的增、刪、改、查功能
問:增刪改查夠了嗎?爲了有良好的體驗,前端頁面顯示的時候需要能夠分頁顯示,操作成功後在前端有信息提示,並需要做重複判斷,這些要如何實現呢?
答:分頁顯示使用PageHelper插件具體使用可以參考:SpringBoot引入Pagehelper分頁插件 ,前端信息提示可以用model.addAttribute,重複添加使用@Valid註解:請求數據校驗,再做一個邏輯判斷就可以了
添加PageHelper分頁插件,在pom.xml中添加:
<!--引入分頁插件--> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.12</version> </dependency>
在admin包下創建TypeController控制器類,代碼如下:
package com.star.controller.admin; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.star.entity.Type; import com.star.service.TypeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import java.util.List; /** * @Description: * @Date: Created in 14:56 2020/6/2 * @Author: ONESTAR * @QQ羣: 530311074 * @URL: https://onestar.newstar.net.cn/ */ @Controller @RequestMapping("/admin") public class TypeController { @Autowired private TypeService typeService; // 分頁查詢分類列表 @GetMapping("/types") public String list(Model model, @RequestParam(defaultValue = "1",value = "pageNum") Integer pageNum){ //按照排序字段 倒序 排序 String orderBy = "id desc"; PageHelper.startPage(pageNum,10,orderBy); List<Type> list = typeService.getAllType(); PageInfo<Type> pageInfo = new PageInfo<Type>(list); model.addAttribute("pageInfo",pageInfo); return "admin/types"; } // 返回新增分類頁面 @GetMapping("/types/input") public String input(Model model){ model.addAttribute("type", new Type()); return "admin/types-input"; } // 新增分類 @PostMapping("/types") public String post(@Valid Type type, RedirectAttributes attributes) { Type type1 = typeService.getTypeByName(type.getName()); if (type1 != null) { attributes.addFlashAttribute("message", "不能添加重複的分類"); return "redirect:/admin/types/input"; } int t = typeService.saveType(type); if (t == 0) { attributes.addFlashAttribute("message", "新增失敗"); } else { attributes.addFlashAttribute("message", "新增成功"); } return "redirect:/admin/types"; } // 跳轉修改分類頁面 @GetMapping("/types/{id}/input") public String editInput(@PathVariable Long id, Model model) { model.addAttribute("type", typeService.getType(id)); return "admin/types-input"; } // 編輯修改分類 @PostMapping("/types/{id}") public String editPost(@Valid Type type, RedirectAttributes attributes) { Type type1 = typeService.getTypeByName(type.getName()); if (type1 != null) { attributes.addFlashAttribute("message", "不能添加重複的分類"); return "redirect:/admin/types/input"; } int t = typeService.updateType(type); if (t == 0 ) { attributes.addFlashAttribute("message", "編輯失敗"); } else { attributes.addFlashAttribute("message", "編輯成功"); } return "redirect:/admin/types"; } // 刪除分類 @GetMapping("/types/{id}/delete") public String delete(@PathVariable Long id,RedirectAttributes attributes) { typeService.deleteType(id); attributes.addFlashAttribute("message", "刪除成功"); return "redirect:/admin/types"; } }
講解:
- @Controller註解:用於標註控制層組件
- @RequestMapping("/admin"):建立請求URL和處理方法之間的對應關係
- @GetMapping註解:一個組合註解,是@RequestMapping(method = RequestMethod.GET)的縮寫,用於將HTTP get請求映射到特定處理程序的方法註解
- @PostMapping註解:一個組合註解,是@RequestMapping(method = RequestMethod.POST)的縮寫,用於將HTTP post請求映射到特定處理程序的方法註解
- @Valid註解:請求數據校驗,用來判斷是否有重複的分類
- @PathVariable註解:獲取URL中的數據
- attributes.addFlashAttribute:相當於重定向後,在URL後面拼接了參數,這樣在重定向之後的頁面後者控制器再去獲取URL後年的參數就可以了
5.前後端交互
1.新增:
<a href="#" th:href="@{/admin/types/input}"> <button type="button" class="ui teal button m-mobile-wide m-margin-top"><i class="pencil icon"></i>新增</button> </a>
2.編輯刪除:
<a href="#" th:href="@{/admin/types/{id}/input(id=${type.id})}" class="ui mini teal basic button">編輯</a> <a href="#" th:href="@{/admin/types/{id}/delete(id=${type.id})}" onclick="return confirm('確定要刪除該分類嗎?三思啊! 刪了可就沒了!')" class="ui mini red basic button">刪除</a>
3.查詢分類列表:
<a href="#" th:href="@{/admin/types}" class="teal active item">列表</a>
4.分頁:
<div class="ui inverted divided stackable grid"> <div class="three wide column" align="center"> <a class="item" th:href="@{/admin/types(pageNum=${pageInfo.hasPreviousPage}?${pageInfo.prePage}:1)}" th:unless="${pageInfo.isFirstPage}">上一頁</a> </div> <div class="ten wide column" align="center"> <p>第 <span th:text="${pageInfo.pageNum}"></span> 頁,共 <span th:text="${pageInfo.pages}"></span> 頁,有 <span th:text="${pageInfo.total}"></span> 個分類</p> </div> <div class="three wide column" align="center"> <a class="item" th:href="@{/admin/types(pageNum=${pageInfo.hasNextPage}?${pageInfo.nextPage}:${pageInfo.pages})}" th:unless="${pageInfo.isLastPage}">下一頁</a> </div> </div>
運行代碼,訪問:http://localhost:8080/admin ,登錄後,點擊分類管理,進入分類管理頁面,可以對分類進行增、刪、改、查
目錄結構如下:
至此,分類管理實現完成,下一篇將講述博客管理
【點關注,不迷路,歡迎持續關注本站】
【SpringBoot搭建個人博客】- 分類管理(六)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.