最新畢業設計乾貨之圖書管理系統
https://www。zhihu。com/video/1430597427640864768
前言
馬上年底了,對於即將畢業的學弟學妹來說,過完年應該是最忙的時候,既要為3-4月份的校園春季招聘做準備,同時又要準備畢業設計。希望本文對這些即將畢業的學弟學妹們、以及剛入門java不久並即將就業的同學們有所幫助,本文將以最簡單的業務模型來講解企業級的java開發是怎麼玩的。
想要原始碼、文件、影片教程的同學請掃碼加我微信
。這裡打個廣告,學長多年bat工作經驗,常年負責校招和社招面試,有興趣的同學可以私信我,我可以提供簡歷輔導和內推~~~)
影片教程
功能設計
領域模型
DO(DataObject):與資料庫表結構一一對應,透過DAO層向上傳輸資料來源物件
BO(BusinessObject):業務物件。由Service層輸出的封裝業務邏輯的物件
VO(View Object):顯示層物件,通常是Web向模板渲染引擎層傳輸的物件
BO和VO領域模型又分為BoRequest(輸入模型)、BoResponse(輸出模型)、VoRequest(輸入模型)、VoResponse(輸出模型)
技術棧
前端:vue + element
後端:jdk1。8 + springboot + redis + mysql
系統設計
表結構設計
CREATE TABLE `account` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘主鍵’,
`passport` varchar(16) NOT NULL COMMENT ‘賬號’,
`name` varchar(6) NOT NULL COMMENT ‘名稱’,
`password` varchar(64) NOT NULL COMMENT ‘密碼’,
`status` int(11) NOT NULL DEFAULT ‘0’ COMMENT ‘使用者狀態’,
`role_id` bigint(20) NOT NULL COMMENT ‘角色’,
`email` varchar(32) NOT NULL COMMENT ‘郵箱’,
`phone` varchar(16) NOT NULL COMMENT ‘手機號’,
`address` varchar(64) DEFAULT NULL COMMENT ‘地址’,
`sex` int(11) NOT NULL DEFAULT ‘0’ COMMENT ‘性別 0:女;1:男’,
`description` varchar(128) DEFAULT NULL COMMENT ‘備註’,
`last_login_time` bigint(20) DEFAULT ‘0’ COMMENT ‘最近登入時間’,
`create_time` bigint(20) NOT NULL DEFAULT ‘0’ COMMENT ‘建立時間’,
`update_time` bigint(20) DEFAULT ‘0’ COMMENT ‘更新時間’,
PRIMARY KEY (`id`),
UNIQUE KEY `passport_UNIQUE` (`passport`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT=‘賬號表’
CREATE TABLE `role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘主鍵’,
`name` varchar(32) NOT NULL COMMENT ‘角色名稱’,
`description` varchar(128) DEFAULT NULL COMMENT ‘備註’,
`authorities` varchar(1024) NOT NULL COMMENT ‘許可權列表’,
`create_time` bigint(20) NOT NULL DEFAULT ‘0’ COMMENT ‘建立時間’,
`update_time` bigint(20) DEFAULT ‘0’ COMMENT ‘更新時間’,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT=‘角色表’
CREATE TABLE `book` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘主鍵’,
`name` varchar(32) NOT NULL COMMENT ‘書名’,
`author` varchar(32) NOT NULL COMMENT ‘作者’,
`publish` varchar(32) NOT NULL COMMENT ‘出版社’,
`publish_time` bigint(20) DEFAULT ‘0’ COMMENT ‘出版時間’,
`language` varchar(16) NOT NULL COMMENT ‘語言’,
`price` decimal(2,0) DEFAULT ‘0’ COMMENT ‘價格’,
`book_class_id` bigint(20) NOT NULL COMMENT ‘圖書分類’,
`stock` int(11) NOT NULL DEFAULT ‘0’ COMMENT ‘庫存’,
`introduction` text COMMENT ‘簡介’,
`create_time` bigint(20) NOT NULL DEFAULT ‘0’ COMMENT ‘建立時間’,
`update_time` bigint(20) DEFAULT ‘0’ COMMENT ‘更新時間’,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT=‘圖書表’
CREATE TABLE `book_class` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘主鍵’,
`name` varchar(32) NOT NULL COMMENT ‘分類名’,
`description` varchar(256) DEFAULT NULL COMMENT ‘備註’,
`create_time` bigint(20) NOT NULL DEFAULT ‘0’ COMMENT ‘建立時間’,
`update_time` bigint(20) DEFAULT ‘0’ COMMENT ‘更新時間’,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT=‘圖書分類表’
CREATE TABLE `borrow_record` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘主鍵’,
`book_id` bigint(20) NOT NULL COMMENT ‘圖書’,
`passport` varchar(128) NOT NULL COMMENT ‘賬號’,
`borrow_time` bigint(20) NOT NULL COMMENT ‘借書時間’,
`expected_back_time` bigint(20) NOT NULL DEFAULT ‘0’ COMMENT ‘計劃還書時間’,
`back_time` bigint(20) DEFAULT NULL COMMENT ‘還書時間’,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8 COMMENT=‘借閱資訊表’
CREATE TABLE `sys_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘主鍵’,
`passport` varchar(128) DEFAULT NULL COMMENT ‘賬號’,
`url` varchar(255) DEFAULT NULL COMMENT ‘請求URL’,
`method` varchar(255) DEFAULT NULL COMMENT ‘請求方法’,
`params` varchar(2048) DEFAULT NULL COMMENT ‘請求引數’,
`ip` varchar(255) DEFAULT NULL COMMENT ‘請求ip’,
`cost` bigint(20) DEFAULT NULL COMMENT ‘請求耗時(單位毫秒)’,
`create_time` bigint(20) NOT NULL COMMENT ‘建立時間’,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT=‘系統日誌’
介面設計
整個專案介面採用的目前網際網路比較流行的restful風格設計,每個介面、每個引數都有詳細的文件說明。因為企業中開發必然是團隊協作,必然前後端分離的開發模式,你得先把介面定義出來,然後前端可以和後端同步開發。還有一種就是對外提供介面,比如你們隔壁團隊也想呼叫你這個服務的介面,但是你兩排期是同一周,這時候你得先把介面定義出來給人家,然後大家同步開發,開發完了之後再進行聯調。
執行效果
系統登入
dashboard
圖書分類管理
圖書管理
為了讓系統更像一個真實的“圖書管理系統”,學長寫了個指令碼,特地從網上爬了10個分類,近600本書,包括書名、作者、簡介等資訊
這裡特地標了“查詢、新建、詳情、借閱、編輯、刪除”幾個按鈕,因為是admin超級管理員,系統內建的超管許可權是擁有所有許可權的,實際上這裡的每一個按鈕都進行許可權管理,可以進行自由組合,比如普通讀者角色,只需要給讀者分配“查詢、詳細、借閱”三個許可權就夠了。許可權還是非常靈活的。
這裡借閱其實也是相對複雜一點的地方,主要是兩點:一個是庫存小於0的時候不能借閱吧?看下面截圖的第四條資料,因為庫存是0,所以是不會展示借閱按鈕的;另一個是庫存只有5本書,但是20個人同時點了借閱,這時候你不能超過庫存數吧?也就是你最多隻能借出去5本書才對,這裡採用的是資料庫樂觀鎖的簡單方式實現。
借閱
借閱必須填寫計劃歸還時間,最多是借閱一個月(引數校驗做得還算很細的,這裡控制元件只能選一個月內的時間,另外多說一句,前端頁面和後端介面,幾乎每個欄位都做了引數校驗,正常公司裡也是這麼做的)。同一本書一次只能借閱一本,只有歸還後才能繼續借閱這本書。
借閱管理
借閱管理分為三個tab頁,“所有借閱”tab頁是可以查詢到所有歷史借閱資訊的,“待還借閱”指的是還未歸還的借閱記錄,“逾期借閱”指的是當前時間大於預計歸還時間的借閱記錄。這裡逾期後系統是沒做額外懲罰邏輯處理的,實際上管理員在逾期使用者還書的時候可以線下罰款,或者一個季度內超過三次逾期將不能繼續借書,或者在逾期前一天給使用者發郵件等,思路有很多,這一塊個人覺得不是重點,大家有好的點子可以自由發揮~~~
還書
讀者還書時將書籍當面交給圖書管理員,圖書管理確認後,在借閱記錄的待還借閱tab頁,透過讀者的賬號搜尋,然後點選還書操作,還書後這本書的借閱記錄會從待還借閱tab頁移除,同時這本書的庫存會加1,到這裡其實核心邏輯就走完了。(至於新增圖書分類、新增書籍、下架書籍等操作,這都是管理員的活,對應的無法就是新增和編輯、刪除按鈕)
日誌管理
日誌管理預設是開給管理員的,在系統中的所有操作都會被記錄,在系統出現異常時也便於管理員進行問題排查。
使用者管理
預設也是隻有管理員擁有使用者管理選單的許可權,可以新建/編輯使用者、分配使用者角色、禁用/啟用等操作
編輯使用者資訊
角色管理
預設也是隻有管理員擁有角色管理選單的許可權,這裡的許可權是細粒度到按鈕許可權的,每個按鈕都可以進行許可權管理,假如給讀者只分配了書籍的“查詢”許可權,但是這個讀者也是個程式設計師,他想透過介面請求直接訪問圖書修改介面,這時候後端是會許可權校驗的,返回“未授權”的錯誤碼,然後前端根據“未授權”錯誤碼會重定向到一個403頁面(這也是為什麼說只有前端校驗是不安全的,後端也必須得校驗,這在實際企業裡開發也是這樣的,還沒有實際開發經驗的學弟學妹拿個小本本記一記,哈哈哈)
普通讀者登入
系統預設會建立兩個角色,一個是超管角色,另一個則是普通讀者角色(當然角色大家可以按前面說的自定義)。普通讀者登入的選單以及選單中的按鈕許可權都會少很多,截圖如下:
我的借閱
個人資訊修改
密碼修改
管理員建立完使用者之後的預設密碼是“123456”,使用者可以登入系統自己修改密碼
許可權設計
許可權基於security和spring-session實現。許可權可以分為認證和授權,認證其實就是登入,使用者登入時會進行賬號密碼的校驗,校驗成功後會,會把session存入redis中。授權指的是使用者是否擁有訪問後端資源的許可權,每個新使用者在建立後都會分配角色,角色其實就是一個許可權集合,這裡的許可權可以理解為訪問後端一個個介面(資源)的許可權。
這裡許可權設計的非常靈活,細粒度到按鈕級別,比如圖書的新增、刪除、修改、查詢、借閱動作,普通讀者可能就只有圖書的查詢和借閱許可權,圖書管理員則擁有新增、刪除、修改的許可權。普通使用者訪問圖書管理模組則只展示查詢和借閱按鈕,即使透過介面直接訪問後端的修改或者刪除介面,後端也會返回授權失敗錯誤,因為後端每個需要許可權的介面都打了許可權標識,只有擁有資源許可權使用者才能訪問。
比如下面的圖書修改介面,只有擁有“BOOK_UPDATE”這個許可權標識的使用者才能訪問這個介面,否則返回“未授權”的錯誤。
@PutMapping
(
“/{id}”
)
@PreAuthorize
(
“hasAuthority(T(com。senior。book。console。api。security。Authority)。BOOK_UPDATE。name())”
)
public
Result
<
Boolean
>
update
(
@PathVariable
(
“id”
)
Long
id
,
@Valid
@RequestBody
BookUpdateVoRequest
request
)
{
}
日誌方案
日誌採用lombok註解+slf4j+log4j2的實現方案,基於profile實現了多環境的日誌配置,因為不同環境的日誌列印策略是不一樣,比如開發環境我可能需要列印到console控制檯,需要debug級別的日誌以便於本地開發除錯,測試環境可能就需要列印到日誌檔案裡,線上環境可能需要列印到檔案的同時將日誌傳送到kafka然後收集到es中,這樣當線上部署了多臺機器後我們查日誌不用一臺一臺機器去查日誌了,因為都收集到es了,我們只需要登入kibana去搜索,這樣就非常方便。這裡說到的kafka+es+kibana這樣一套日誌解決方案也是目前網際網路公司比較常用的一套解決方案。如果你動手能力夠強,你可以本地搭一套kafka、es、kibana,然後只需要在配置檔案中加入幾行配置就實現了這麼一套企業級的日誌解決方案(預設是輸出到日誌檔案)。
下面是部分關鍵配置,如果要配置kafka,只需要在標籤中配置配置即可
<?xml version=“1。0” encoding=“UTF-8”?>
status= “WARN” xmlns:xi= “http://www。w3。org/2001/XInclude” > name= “LOG_FILE” > system。log name= “LOG_PATH” > 。/logs name= “PID” > ???? name= “LOG_EXCEPTION_CONVERSION_WORD” > %xwEx name= “LOG_LEVEL_PATTERN” > %5p name= “LOG_DATE_FORMAT_PATTERN” > yyyy-MM-dd HH:mm:ss。SSS name= “CONSOLE_LOG_PATTERN” > %clr{%d{${LOG_DATE_FORMAT_PATTERN}}}{faint} %clr{${LOG_LEVEL_PATTERN}} %clr{${sys:PID}}{magenta} %clr{——-}{faint} %clr{[%15。15t]}{faint} %clr{%-40。40c{1。}}{cyan} %clr{:}{faint} %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD} name= “FILE_LOG_PATTERN” > %d{${LOG_DATE_FORMAT_PATTERN}} ${LOG_LEVEL_PATTERN} ${sys:PID} ——- [%t] %-40。40c{1。}:%L : %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD} href= “log4j2/file-appender。xml” /> name= “com。senior。book” level= “info” /> level= “info” > ref= “FileAppender” />
服務監控
朋友們,馬上2021年了,別再讓你的服務光著屁屁在伺服器上“羅。奔”了
服務監控基於 Actuator + Prometheus + Grafana 實現,程式碼侵入很小,只需要在pom中加入依賴。資料大盤Dashboard可以自己設定,也可以去Dashboard市場下載你想要的模板,總之,這塊完全是看動手能力,大家自己玩吧~~~
<!——服務監控——>
org。springframework。boot
spring-boot-starter-actuator
io。micrometer
micrometer-registry-prometheus