SpringBoot+Vue实现简单用户管理平台第一篇(后端接口设计)
- 🚀 注重版權,轉載請注明原作者和原文鏈接
- 🥭 作者:Yuan-Programmer
- 🍎 主頁:https://blog.csdn.net/weixin_47971206/article/details/121368075?spm=1001.2014.3001.5502
- 🍉 進來的小伙伴點點贊呀
本案例第二篇教程地址:SpringBoot+Vue實現簡單用戶管理平臺第二篇(前端設計,接口對接)
demo地址預覽(域名正在審核,將就ip訪問):http://43.138.223.178/user-manager
花了幾個小時做了一個SpringBoot+Vue的簡單用戶管理demo項目,適合新手教程,項目已在Gitee上開源,Gitee開源地址:https://gitee.com/yuandewei/Yuan-SpringBoot/tree/master
Gitee上開源的代碼跟本次的案例的代碼有些區別,本次案例稍微改了一點點,不過不影響Gitee上的項目運行,大致效果如下,功能可以訪問demo地址測試哦
前言
開發環境
開發工具就不多介紹啦,就IDEA做后端,VSCode做前端,用其他的也都可以
技術
本次后端用到的技術呢: 主要就兩個,SpringBoot + MyBatisPlus
前端的技術用到的技術: Vue,結合腳手架以及element ui框架開發前端
表設計
既然是用戶管理嘛,肯定有用戶表,我們先來設計表結構
這里說明一點,這次案例是新手教程,著重講解功能的實現,所以用戶信息參數方面就沒有那么嚴格的校驗,一般像號碼這種字段肯定是設置為 char(11) 并且后端要校驗的
創建Maven工程
創建一個空的Maven項目,大家應該都會了吧,還不會的小伙伴看之前的其他項目教程哦(我個人習慣創建maven工程,你喜歡直接創建springboot項目也可以,)
我這里創建好了一個 user-manager的maven項目,創建好項目,點擊右下角選擇自動導入,沒有彈出來也沒關系
引入依賴
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.1.RELEASE</version><relativePath/></parent><properties><java.version>1.8</java.version></properties><dependencies><!-- MyBatis-Plus依賴 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.0</version></dependency><!-- 數據庫驅動 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!-- Web啟動依賴 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- SpringBoot測試依賴 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- Lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- 處理JSON的 --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.76</version></dependency></dependencies>基本配置
創建 com.xiaoyuan.usermanager 目錄,新建一個啟動類 UserManagerApplication
在 resources 資源目錄下新建 application.yml 配置文件
圖片有誤,少了時間格式轉換三行代碼,看下面
server:# 端口port: 8081spring:# 數據源配置datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql:///l_user?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8username: xiaoyuanpassword: root# 時間格式轉換jackson:time-zone: GMT+8date-format: yyyy-MM-dd HH:mm:ssmybatis-plus:# mapper文件映射路徑mapper-locations: classpath*:mapper/*.xmlconfiguration:# 打印SQL語句log-impl: org.apache.ibatis.logging.stdout.StdOutImpldb層
entity實體類
新建 db 包,在 db 包下新建 entity 和 mapper 兩個包,在 entity 包下新建一個 User 類
注意一下,圖片里 describe 有個注解忘記加上了,以下面代碼為準
@Data public class User {// 主鍵ID@TableId(value = "id", type = IdType.AUTO)private Integer id;// 用戶名private String username;// 昵稱private String nickname;// 密碼private String password;// 號碼private String phone;// 性別private Character sex;// 描述@TableField(value = "`describe`") // describe屬于數據庫關鍵字,加上``區分private String describe;// 創建時間@TableField(fill = FieldFill.INSERT) // insert操作時自動注入時間private Date gmtCreate; }mapper數據訪問層
在 mapper 包下新建一個 UserMapper,繼承MyBatisPlus的 BaseMapper 類,作為DAO層操作數據
MyBaitsPlus配置
這里創建的兩個包都與db包同級目錄
config配置類
創建一個config包,新建一個MyBatisPlusConfig 類
@Configuration public class MyBatisPlusConfig {/* 分頁插件 */@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 開啟interceptor.addInnerInterceptor(new PaginationInnerInterceptor());return interceptor;} }handler處理
新建一個 handler 包,包下新建一個 MyMetaObjectHandler 類,實現 MetaObjectHandler 類,改類有兩個方法,一個insert…在向數據庫插入數據的時候,會自動插入我們設置的值
@Component public class MyMetaObjectHandler implements MetaObjectHandler {/*** 新增數據執行* * insert插入數據到數據庫操作時執行*/@Overridepublic void insertFill(MetaObject metaObject) {// 配置初始創建時間this.setFieldValByName("gmtCreate", new Date(), metaObject);}/*** 修改數據執行* * update修改數據庫數據操作時執行*/@Overridepublic void updateFill(MetaObject metaObject) {} }這里的 this.setFi… 第一個參數對應的是User實體類的名字,不是表中的字段名,第二個參數的默認值
Vo對象
新建一個 vo 包,用于和前端交互數據的類
統一結果返回類
vo 包下新建一個 R 類,作為我們統一返回給前端數據的類,
@Data public class R {private Boolean success;private Integer code;private String message;private Map<String, Object> data = new HashMap<>();// 把構造方法私有化private R() {}// 成功靜態方法public static R ok() {R r = new R();r.setSuccess(true);r.setCode(200);r.setMessage("成功");return r;}// 失敗靜態方法public static R error() {R r = new R();r.setSuccess(false);r.setCode(201);r.setMessage("失敗");return r;}public R success(Boolean success){this.setSuccess(success);return this;}public R message(String message){this.setMessage(message);return this;}public R code(Integer code){this.setCode(code);return this;}public R data(String key, Object value){this.data.put(key, value);return this;} }vo 包下新建 QueryParam 類
@Data public class QueryParam {// 用戶名private String username;// 昵稱private String nickname;// 號碼private String phone;// 性別private String sex;// 創建時間private String time; }這里講一下吧,這個類是用來干嘛的呢?我們在效果展示的時候,是不是在上面看到有5個篩選條件,這5個篩選條件參數剛好對應類中的5個屬性,我們統一封裝起來
service業務層
新建一個 service 包,包下新建一個 UserService 接口類,繼承MyBatisPlus的 IService 類
service 包下新建 impl 包,新建一個 UserServiceImpl 實現類,繼承MyBatisPlus的 ServiceImpl 類,實現我們自己的 UserService 類
我們先在 UserService 接口類定義五個方法,接下來我們一一實現這五個功能
添加用戶
UserServiceImpl 實現類里實現添加用戶方法,這里只做了簡單的非空判斷,其他參數的非法性校驗可以自己額外完善
@Override public R insertUser(User user) {if (user == null) return R.error().message("參數錯誤");// 用戶名String username = user.getUsername();// 構建條件對象, 查詢是否已經存在用戶名QueryWrapper<User> wrapper = new QueryWrapper<>();wrapper.select("id");wrapper.eq("username", username);wrapper.last("limit 1");// 查詢判斷, 如果查詢出來有數據, 則不為nullif (this.baseMapper.selectOne(wrapper) != null) R.error().message("該用戶名已存在");// 執行插入數據操作return this.baseMapper.insert(user) == 0 ? R.error().message("添加用戶失敗") : R.ok(); }刪除用戶
刪除用戶就比較簡單啦,肯定有人會問,前端做了非空校驗,后端怎么還要做參數校驗校驗呢?
其實前后端都做是最好的,有繞過前端發送請求的,就比如我們自己測試接口時用的postman, apifox,后端多做一層校驗,避免直接操作數據庫,我這里也是比較簡單的做了校驗
@Override public R deleteUser(Integer id) {if (id == null || id <= 0) return R.error().message("參數錯誤");return this.baseMapper.deleteById(id) == 0 ? R.error().message("刪除失敗") : R.ok(); }一鍵刪除多個用戶
刪除多個用戶也沒難度,將多個用戶的編號放到一個集合中,一次刪除多個
@Override public R deleteUserMore(List<Integer> ids) {if (ids.size() == 0) return R.error().message("參數錯誤");return this.baseMapper.deleteBatchIds(ids) != ids.size() ? R.error().message("刪除失敗") : R.ok(); }編輯用戶
這個也沒什么難度,做個簡單校驗,然后根據ID更新用戶信息(參數其他合法性校驗可以自己額外做哦)
@Overridepublic R modifyUser(User user) {if (user == null || user.getId() == null || user.getId() <= 0) return R.error().message("參數錯誤");return this.baseMapper.updateById(user) == 0 ? R.error().message("編輯用戶失敗") : R.ok();}獲取單個用戶信息
先實現這個吧,這個也很簡單,直接通過用戶編號查詢用戶的信息返回即可
@Override public R getUserInfoById(Integer id) {if (id == null || id <= 0) return R.error().message("參數錯誤");return R.ok().data("userInfo", this.baseMapper.selectById(id)); }查詢用戶列表
先創建編寫SQL語句的文件,在 resources 下新建 mapper 包,包下新建 UserMapper.xml 文件
代碼中的SQL語句不能包含注釋,所以我在圖片給出了每行的注釋,代碼中刪掉了,對應看著
我們大致來分析一下上面的SQL語句,首先 select * from user這里沒毛病吧,咋們是管理用戶,所有信息都得要上,* 查詢所有
后面 where 里有個 1 = 1 作用是恒等式,為了防止沒有做篩選條件時,queryParam 條件對象為 null 導致 where 里面沒東西,執行SQL語句的時候就會出現 where 后面沒加東西,就會拋出異常
CONCAT 函數的作用是拼接,當然你直接用下面這樣也行,推薦還是使用CONCAT,以后會遇到的,還有就是 % 只寫右邊就可以了,避免全表掃描,采用單模糊查詢
and nickname like #{queryParam.nickname} '%'DATE_FORMAT 函數作用是對時間進行格式化,2022-05-06 11:17:36 轉換為 2022-05-06
SQL語句寫好了,更新一下我們的 UserMapper 類,映射到 UserMapper.xml 文件的SQL語句,函數名就是 < select id=“xxxx”> 這里id的值
@Repository public interface UserMapper extends BaseMapper<User> {/*** 查詢用戶列表* @param page 分頁對象* @param queryParam 篩選條件* @return*/IPage<User> findUserList(Page<User> page, QueryParam queryParam); }最后就是在 UserServiceImpl 實現查詢用戶列表的方法
@Override public R findUserList(Integer index, Integer size, QueryParam queryParam) {if (index == null || size == null || index <= 0 || size <= 0) {return R.error().message("參數錯誤");}else if (size > 10) {return R.error().message("一次最多10條數據");}// 構建分頁對象Page<User> page = new Page<>(index, size);// 查詢IPage<User> iPage = this.baseMapper.findUserList(page, queryParam);// 回傳兩個數據, 一個 userList --> 用戶數據列表, 一個 total -> 總頁數return R.ok().data("userList", iPage.getRecords()).data("total", iPage.getTotal()); }controller控制層
這里是最后一步了,處理接口,我們采用 RESTful 的風格,相同的路徑處理不用的操作
接口測試
最后,在啟動類加上兩個注解,一個 MapperScan 掃描我們的 mapper 類,一個 ComponentScan 掃描我們的組件
@SpringBootApplication @MapperScan(basePackages = {"com.xiaoyuan.usermanager.db.mapper"}) @ComponentScan({"com.xiaoyuan"}) public class UserManagerApplication {public static void main(String[] args) {SpringApplication.run(UserManagerApplication.class, args);} }OK,到這里功能已經全部做好了,我們測試一下接口,運行啟動類,我這里只展示部分接口的測試接口,全部接口我已經測試過,都沒有問題了
大家可以自己去測試每個接口,我用的時 ApiFox 工具,非常好用,還能一鍵導出接口文檔,可以顯示接口耗時,分組分項目分接口分環境,非常的方便
添加用戶,成功插入數據
當然,你可以在代碼里面用測試,新建一個 SpringBoot 的測試類,測試業務層也可以的,如下
其他的就不一一放出來了,大伙自己去試試吧~
擴展(攔截器,權限攔截)
像管理這種一般都會有權限的,總不可能每個人都能訪問自己的接口來增刪改查用戶吧?如何做到不給其他人訪問自己的接口,判斷別人是否有權限訪問呢?
下面我們簡單來設計一下,理解大概過程
首先,usermanager 主目錄下創建兩個包,一個 interceptor 攔截器,一個 WebMVCConfig MVC的配置類
interceptor 包下新建一個 PermissionInterceptor 類,實現 HandlerInterceptor 類
攔截器有三個階段,preHandle -> postHandle -> afterCompletion,依次按順序執行,只有前一個return返回true,才會執行下一個階段方法,簡單介紹三個階段
- preHandle:controller執行目標方法之前執行,一般用于權限驗證等操作
- postHandle:controller執行完目標方法返回(如調用service業務層的方法),在前端數據渲染之前執行,一般用于更改視圖數據
- afterCompletion:整個接口訪問執行完畢,前端數據渲染完成,執行此方法,一般用于資源釋放等操作
很明顯,我們這個權限驗證攔截就是在 preHandle 階段去全性
這個 code 呢就是我們自己定義的權限碼,我這里只是隨便敲了長長的一段,反正自己知道就好,你可以做加密處理,這里我簡單模擬一下
@Component public class PermissionInterceptor implements HandlerInterceptor {private static final String code = "dwagfhwhgiawpfwabifpjwaidjwaidwiafihwigfhwaigwhaipgwaihiwahifhwdefef";@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 放行OPTIONS請求if (HttpMethod.OPTIONS.matches(request.getMethod())) {return true;}// 獲取請求頭里面的 Authentication 屬性值String authentication = request.getHeader("Authentication");// 兩者相等 -> 通過放行, 兩者不相等 -> 不通過不放行if (code.equals(authentication)) {// 放行return true;}else {// 不放行, 回傳沒有權限response.setContentType("text/html;charset=utf-8");response.getWriter().println(JSON.toJSONString(R.error().message("沒有操作權限")));return false;}} }config 包下新建一個 WebMVCConfig 類,實現 WebMvcConfigurer 類,設置攔截器
@Configuration public class WebMVCConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new PermissionInterceptor()) // 添加攔截器.addPathPatterns("/user/**"); // 選擇攔截路徑,攔截/user下的所有請求} }好的,我們接下來看看效果,當然,就不適合在代碼用SpringBoot測試類啦,因為校驗請求頭
我們采用接口測試工具,老樣子,我使用的是ApiFox,你可以使用postman等其他工具
首先我們繼續運行一下之前寫好的請求路徑(沒加Authentication 權限碼),可以看到,我們訪問的是查詢用戶列表接口,顯示沒有權限
接下來我們在 header 請求頭加上我們的 Authentication 的權限碼,同樣的路徑,測試一下
是不是就成功訪問到了
我們隨便改錯一個字母,也成功顯示沒有權限,除非你的權限碼被別人知道了,或者被破解了(設置的復雜一點再加密基本不可能被破),不然你的接口別人訪問不了
🌹 結束語
好了,整篇的教程呢到這也就結束,整篇教程即為原創一字一字手敲,也花了心思想怎么寫怎么設計才能更好的直觀簡潔展示給大家,讓大家能看懂
最后,關于教程還有什么不懂的可以評論區留言,我一定會回復的,或者有什么更好的建議和想法也可以在評論區留言,看到好的我會一一采納,感謝大家的支持
再一次附上Gitee開源地址:https://gitee.com/yuandewei/Yuan-SpringBoot/tree/master 不用大伙翻上去復制了
- 都看到這里啦,點點贊呀 😋
- 感謝閱讀 😘
總結
以上是生活随笔為你收集整理的SpringBoot+Vue实现简单用户管理平台第一篇(后端接口设计)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: intellij idea cpu占用率
- 下一篇: 24岁我有了自己的公司