後臺管理系統很簡單? 就是CRUD? 快進來看看你忽視了多少細節!

前言

今年下半年負責了一個前後端分離的管理系統, 用的是 Springboot + Spring data jpa + Vue + mysql, 個人負責的是後端接口開發, 這也算是我第一次從 0 到 1 完成的一個管理系統.

受制於平時看的視頻教程, 亦或者是一些開源項目, 以及平時養成的壞習慣, 導致在真正上手去做這些 平時看不起 的管理系統時, 踩了很多坑, 忽略了很多細節, 希望這篇文章不僅能讓自己得到反思, 也能幫助其他人一起脫坑!!!

正文

下面會通過管理系統幾個必備的功能, 必要時還會給出 案例 來說明細節的重要性.

一、後端接口開發

永遠不要想着你的接口只會提供給前端界面去使用, 從而導致你認爲只要前後端約定好一切就萬事大吉了, 只要產生了這個前提, 在你做測試的時候, 就會站在前端調用的角度去做接口測試, 有時甚至界面上的功能點一點就行了, 這樣只能說明通過界面去使用你們的系統是 ok 的. 一旦接口暴漏給第三方開發者去使用, 你就會發現提供出去的接口服務完全經不起折騰.

例子 1: 有一張圖片資源表, 表結構如下, 這張表是保存了所有用戶的圖片資源, 在管理界面上用戶只能看到自己的圖片列表.

id(主鍵) name user_id
1 圖片1 11111

當我們做查詢接口時, 往往能想到通過 user_id 去查詢, 但是當通過做刪除接口時, 因爲能夠通過主鍵 id 定位一條數據, 所以如果只提供 id 作爲刪除請求的參數, 此時通過界面去執行刪除操作,完全看不出有什麼問題, 因爲用戶只能看到用戶自己的圖片, 但是如果此接口提供給第三方開發去掉用, 他就很可能有意無意的把其他用戶的圖片 id 傳遞過來, 這不就壞事了嘛!!!

例子 2: 有一個用戶編輯接口, 用戶表有一條叫 zhangsan 的用戶數據, 要求用戶表的用戶名不能重複, 因此在做唯一性校驗時就自然而然產生了如下僞代碼:

User user = getUserByName("zhangsan");
if(user != null ) {
	return "用戶名已存在";
}
updateUser(updateUser);
return "更新成功";

同時前後端約定了當更新用戶信息時, name 不是必填項, 另外對於非必填項, 前端傳遞 null 值. 此時站在前端的角度上, 確實不能看出這個接口有什麼問題.

但是站在第三方開發者角度上, 你的 name 是可選的, 我在編輯 zhangsan 用戶時, 我就想把 name=zhangsan 重新帶過去, 此時再看一下上面的僞代碼是不是就有問題了?!

二、 用戶登錄

站在 使用者 的角度上, 用戶登錄就是 “在登錄頁輸入用戶名和密碼, 登錄成功後, 進入主頁.”

作爲 開發者 來講, 我們一般更關注的是前後端的一堆校驗邏輯, 比如字段的長度限制, 數據庫唯一性限制.

但是站在 產品設計 的角度上, 需要考慮到 使用者 的各種 “奇葩行爲”, 比如:

  1. 用戶在瀏覽器登錄成功後, 進入主頁, 然後打開一個新的標籤頁, 把主頁網址複製到地址欄中, 你是希望用戶 重新登錄 還是不需要再登錄
  2. 是否允許用戶的同一賬號在多個瀏覽器登錄
  3. 如果用戶長時間不操作, 怎麼實現自動退出登錄

如果要實現上述某一項需求, 作爲開發者的你能否立馬想到用哪些知識點可以解決.

三、用戶權限

用戶權限的入門級 “套路”, 就是 5 張表:

  1. 用戶表
  2. 角色表
  3. 權限表
  4. 用戶-角色關聯表
  5. 角色-權限關聯表.

再不然就是 3-4 張表, 通過在用戶表中添加對應角色表的“虛擬外鍵”, 或者在角色表中添加對應權限表的“虛擬外鍵”, 來實現表之間的關聯.

這樣的套路足以應付絕大多數的系統權限設計, 並且一般的系統權限就是控制一下用戶能夠訪問哪幾個菜單欄就好了, 一旦產品需要你將權限粒度控制到一個按鈕、甚至一行數據(數據權限), 你的套路就變成死路了.

四、查詢數據

說起查詢數據, “小年輕” 的內心 OS 就是“查詢數據多簡單啊, 一條 select 語句而已, 如果多表關聯查詢就用 join 、子查詢之類的”.

no no no~~~ 千萬不要這麼想! 需要考慮的還有很多.

1. 提出2個問題:

  1. 你的模糊查詢功能支持 百分號、下劃線這種字符嗎? 如果不支持, 你覺得這算是問題嗎?

  2. 當你的 where 條件後面的跟的字段值允許爲 null 時, 比如這條語句 select * from user where name!=123 , name 爲 null 的數據能查出來嗎?

2. 查詢優化:

比如你用的 mysql 數據庫中有一張日誌表, 日誌的搜索條件可以有很多, 比如根據日期範圍, 模糊查詢, 狀態查詢, 首先這幾個功能肯定都不難, 我們通常的做法就是模擬幾十條數據, 然後測試單個查詢, 多條件查詢, 當查詢結果符合預期時, 我們就覺得完事兒了, 其實我們忽略了最重要的一點, 這可是日誌表啊, 數據龐大起來可以達到十萬級、百萬、甚至千萬啊, 你只用了幾十條數據測了一下, 發現幾十毫秒就返回了正確結果. 這種測試用例不足以證明功能完成了.

當然, 現在網上關於 mysql 查詢優化的那幾條準則,甚至一些實戰優化文章到處都是, 但是你真的有實踐過嗎, 如果沒有的話, 建議你用上面的日誌表嘗試一下單表優化.

這裏再出多表查詢優化的題目:

一個客戶對應 N 多個標籤, 一個標籤對應 N 多個客戶, 這樣一個多對多關係, 你如何設計表? 如何做查詢優化去優化用戶體驗?

當然也有的人會說我們用的是 Oracel 數據庫, 甚至 Elastic Search 這種搜索引擎... 那就當我沒說

五、 新增數據(提交表單)

前後端分離模式基本都是通過 json 格式的數據進行交互, 比如新增一個用戶, 我們會傳遞類似這樣的參數:

{
	"username": "zhangsan",
	"my_xxx": "我的 xxxx"
}

需要注意的是 my_xxx 這個字段, 有的人在遇到多個單詞拼成的字段時, 喜歡用下劃線分隔開, 這裏也埋了一個坑.

目前爲止, 上面的做法沒什麼問題, 如果此時產品要求新增用戶支持上傳頭像, 並且是同步上傳, 你該如何處理? 如果你採用 form/data 的方式去提交表單, 這時就不能用傳遞 json 數據了, 但是也不能讓後端定義一個 my_xxx 的字段去接受你的參數, 這也違背了 java 編碼規範啊, 如果你繼續採用通過請求體去提交數據, 那隻能將圖片轉爲 base64 編碼.

這裏還要問一句, 你們的系統是用的同步上傳文件, 還是異步上傳文件, 如果是異步上傳文件, 後臺處理時出現異常, 怎麼刪除文件? 有考慮過嗎?

最後要考慮的是如何防止重複提交表單數據? 你的功能需不需要防止?

六、更新數據

更新數據有兩個細節需要注意, 當然這個是有前提條件**, 一個是當你更新的字段與同一張表中的另一個字段有關聯時, 另一個是當你更新的數據與另一張表的字段有關聯時.**

舉兩個不恰當的例子:

例子 1

有一張用戶表, 有 N 多個字段, 其中包括如下三個字段, 可以看到 description 字段是由 name 字段和 age 字段,組合而來的, 格式: 他的名字是{name}, 今年 {age} 歲, 並且這個字段暫時不用在界面上展示, 因此不管是更新 name 字段還是 age 字段, 都是需要更新 description 字段的 .

name age description
zhangsan 18 他的名字是zhangsan, 今年 18 歲

這裏強調了兩點, 1. 這張表有 N 多個字段, 2. 這個字段暫時不用在界面上展示. 另外加上當你使用一些全自動 Dao 層框架時, 你做更新數據, 往往是調用框架的 API 去做的更新, 比如 userDao.update(user). 這就會導致你在測試的過程忘記去觀察 description 字段的變化.

例子 2

早期你有一張角色表, 角色名字段爲 name, 長度限制 50.

後期加了一張 xx 資源表, 同樣有個 name 字段, 長度限制 100, 有一個需求是, 當你在資源表插入 name=哇哈哈 這樣一條數據時, 需要在角色表中插入一條, name=哇哈哈管理員 的數據. 你在測試之前, 是否能否意識到兩張表的長度不一致問題?

七、 刪除數據

刪除數據需要考慮如下問題:

  1. 先查詢到, 再刪除, 如果查詢不到, 接口提示數據不存在
  2. 直接刪除, 不管數據在不在, 都返回刪除成功!
  3. 批量刪除大量數據這種耗時操作應當如何處理?

八、數據導入與導出

2 道選擇題: csv 還是 excel ? poi 還是 easyexcel?

1. 數據導入

數據導入時, 如何解決亂碼問題? 判斷文件編碼你有做嗎? 還是說提供給用戶一個導入模版?

2. 數據導出

這裏仍然牽扯到大數據量問題, 再說一句, 不要隨便拿幾條數據測測就完了, 當導出的數據超過上百萬, 甚至千萬, 如何處理? 怎麼避免內存溢出的問題?

總結

本文突出的重點就是 細節, 一個簡單的管理系統, 不管模塊再多, 無非就是上面所說的八大功能, 每個功能都暗藏了許多細節.

這些細節被忽略的原因大致如下:

  1. 壓根沒有碰到類似的需求
  2. 測試不夠仔細, 通常就是界面點點沒問題就行了
  3. 覺得不重要, 不影響, 比如大數據量查詢, 可能自身接觸的系統沒多少數據,不需要浪費時間優化
  4. 眼高手低, 覺得看看就會了, 思路被一些視頻教程, 文章帶着走, 完全沒有自己的思考
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章