Spring Boot項目開發實戰——銷售管理系統
在前面的章節中我們詳細介紹了Spring Boot各個功能的使用,本章將新建一個銷售管理系統項目,演示項目從需求分析到功能分解,再到各個功能的實現過程,最后再使用Docker部署上線的完整過程。本章將從實際開發的角度介紹Spring Boot及其各個組件,讓讀者對Spring Boot的理解更加深刻。
系統設計
系統設計是在項目初始階段對項目的整體規劃,包括項目需求分析、項目的邊界規劃、項目開發人員安排、項目時間安排(開發時間、測試時間、交付時間)、項目性能設計、代碼規范制定、API規范制定、技術難點預估和調研等。系統設計是進行項目開發的第一步,在進行系統設計時需要完成以下工作:
用思維圖列舉系統中的所有角色和各個角色之間的關系;
用時序圖繪制出所有復雜的工作流程;
用類圖定義出滿足部分功能的類關系,列舉出類屬性、方法、抽象層和接口類等,設置類與類之間的關系;
用E-R圖設計系統表之間的關系。
系統介紹
上海兮索電力科技發展有限公司是一家從事電氣制造和銷售的公司,該公司的弱電設備業務遍布全國各地。在日常的運營過程中該公司發現,當前的客戶管理、產品管理、客戶的跟進、訂單管理已不能滿足公司發展的需要,一部分日常的煩瑣工作需要實現電子化,以提高工作效率,更加方便、快捷地完成對銷售任務的跟進和客戶的管理。因此需要開發一套銷售管理系統,這套銷售系統能徹底解決公司在客戶管理、產品管理、訂單管理等方面的現存問題。因此公司立項開發一個銷售管理系統在互聯網中運行使用。
本項目是一個功能比較簡單的銷售管理系統,其主要作用是將銷售人員和管理者的日常工作電子化,包括銷售員登錄管理、客戶管理、客戶的跟進、產品管理、銷售訂單管理、銷售員的日程管理等功能。銷售人員登錄系統后可以進行客戶管理、客戶跟進和銷售訂單的管理工作。系統要具備權限設置,銷售人員只能查看自己的客戶和自己的訂單,管理人員擁有系統的所有權限,可以查看所有的信息,包括所有銷售人員的訂單信息和客戶信息。根據公司目前的規模,本系統的使用者總人數為30~50人,其中,管理者為5~6人,其他都是普通的銷售人員。系統需要在外網中使用,方便銷售人員能夠隨時通過互聯網進行工作。
未來,隨著公司規模的擴大,系統的使用者可能會達到80人,每個人的客戶可能會超過100個,每個客戶每個月可能會產生3個左右的訂單,每個客戶每月可能需要跟進10次,需要系統能滿足公司未來3~5年使用業務的需求。
系統功能需求分析
需求分析的目標是將產品的需求功能梳理出來,并且用通俗易懂的文字進行描述,為開發人員和測試人員提供依據。需求分析的基本任務是:準確地回答“系統必須做什么”這個問題,也就是對目標系統提出完整、準確、清晰、具體的要求。
需求分析一般分為以下4步:
(1)獲取需求:了解所有用戶類型,包括潛在用戶類型,以確定整體目標和方向。這一步需要完成以下工作:
對用戶進行訪談和調研,對各個角色的需求進行歸納、整理和分析。
業務需求方面,模擬業務場景,對業務邏輯和業務流程進行梳理,整理出業務需求。
(2)根據系統分析需求,完成以下4項工作:
根據業務邏輯和業務流程畫出流程圖,分析業務需求及業務數據的流動順序(完成數據流圖:Data flow Define;ERD用戶用例:use case的繪制)。
挖掘每個需求點的產生原因及實際的作用。
挖掘每個需求點的隱含需求及需求的前置條件。
挖掘每個需求的必要性。
(3)需求確認:整理分析階段的所有需求,確保需求一致。這一步需要
完成以下工作:
整理不清晰的需求。
分別與對應用戶確認以上需求點,保證需求的一致性和清晰性。
(4)編寫需求文檔:使用自然語言,以通俗易懂的語言展現需求分析,可以添加圖形輔助閱讀。輸出文檔包括功能需求和非功能需求,并且最好把原始需求加入需求文檔中,作為一個章節單獨列出。
整個系統的用戶分為兩類:第一類是普通的銷售人員,第二類是管理員(是一類權限更高的銷售人員)。
普通銷售人員的權限包括查看產品、創建訂單、創建客戶、查看客戶、創建待辦任務等,管理員除了擁有普通銷售人員的所有權限之外,還能對系統的用戶進行管理,并且管理員能看到所有用戶的數據,而普通銷售人員只能看到自己創建的用戶數據。
普通銷售人員在系統中有6個權限,具體如下:
創建產品、修改產品和刪除產品:主要是為了與訂單模塊功能關聯使用,訂單能夠關聯具體的產品,公司從而能夠知道哪一類產品的銷量最好,能夠最好地創造利潤。
創建客戶、修改客戶信息和刪除客戶:對客戶信息進行管理。
創建客戶的跟進記錄、修改跟進記錄、刪除跟進記錄:幫助銷售人員跟進客戶,與客戶經常聯系,提高成交率。
創建和刪除訂單目標:為銷售人員設定一段時間內的訂單目標額,幫助銷售人員制定業績目標。
創建待辦事項和刪除待辦事項:幫助銷售人員安排自己的個人事項,將事項按照輕重緩急進行排序,以便更好地完成銷售工作。
修改個人信息和密碼:個人信息的個性化。
管理員擁有普通銷售人員的所有權限,還可以新增普通銷售人員、重置普通銷售人員的密碼及刪除普通銷售人員。
系統用例分析
UML的一個重要圖示就是用例圖,用例圖用于描述系統功能的動態視圖,其由參與者(Actor)、用例(Use Case)及它們之間的關系構成。要在用例圖上顯示某個用例,可繪制一個橢圓,然后將用例的名稱放在橢圓的中心或橢圓下面的中間位置即可。
用例圖中繪制一個參與者(表示一個系統用戶),即繪制一個人形符號。參與者和用例之間的關系使用帶箭頭或者不帶箭頭的線段來表示,箭頭的起始點是對話的主動發起者,箭頭所指方是對話的被動接受者。
用例圖是系統需求分析結果之一,用例圖的主要作用是描述參與者和用例之間的關系,幫助開發人員對系統有可視化的了解。借助于用例圖,系統用戶、系統分析人員、系統設計人員和領域專家能夠以可視化的方式探討問題,大量減少了交流上的障礙,便于對問題達成共識。用例圖可以可視化、方便地表現系統的需求,具有直觀、規范等優點,克服了純文字性說明的不足。用例方法完全從外部來定義系統功能,它把需求和設計完全分離開。設計者不用關心功能是如何實現的,對于設計者來說系統是一個黑盒。用例之間還存在一些關系,如包含、擴展、泛化。
任何用例圖都不能缺少參與者,任何參與者必須要與用例關聯。因此識別用例的最好方法就是從分析系統參與者開始,在這個過程中往往會發現新的參與者。在實際開發中可以通過以下問題來尋找用例:
(1)參與者希望系統能完成什么功能。
(2)參與者是否會讀取、創建、修改、刪除和存儲系統的業務信息,如果是,參與者是如何完成這些操作的。
(3)參與者是否會向系統通知外部的某些事件。
(4)系統中發生的事件是否通知參與者。
(5)是否存在影響系統的外部事件。根據以上系統功能分析,普通用戶具有客戶管理、產品管理、訂單管理、業績目標管理的權限,管理員具有普通用戶的所有權限并且還有用戶管理的權限。
整個系統的用例圖如圖9.1所示。
時序圖描述的是系統中對象之間進行交互的先后順序,在交互過程中建模成消息交換,描述了對象之間期望的信息交換和返回結果,時序圖中每條消息表示對象的一個操作或者引起狀態機改變的觸發事件。
時序圖包括4個元素:對象(Actor)、生命線(Lifeline)、控制焦點(Focus of Control)和消息(Message)。對象(Actor)為系統角色,可以是人甚至其他系統或者子系統。對象(Actor)有3種命名方式:
包括對象名和類名;
只顯示類名不顯示對象名,即表示它是一個匿名對象;
只顯示對象名不顯示類名。
生命線(Lifeline)在時序圖中表示為從對象的圖標向下延伸的一條虛線,表示對象存在的時間。控制焦點(Focus of Control)是時序圖中表示時間段的符號,用小矩形表示,其代表在這個時間段內對象將執行的相應操作。消息(Message)一般分為同步消息(Synchronous Message)、異步消息(Asynchronous Message)和返回消息(Return Message)。
普通用戶創建產品的步驟如下:
(1)單擊“創建產品”按鈕,跳轉到創建產品頁面。
(2)用戶輸入產品信息,單擊“保存”按鈕保存信息。
(3)服務器收到保存請求后對用戶輸入的參數進行校驗,然后再將其保存到數據庫中。
(4)系統將創建成功后的產品列表返回給用戶。
根據以上步驟創建時序圖,如圖9.2所示。
用戶登錄系統的步驟如下:
(1)用戶輸入localhost:8085網址,頁面跳轉到登錄頁面。
(2)用戶輸入賬號和密碼,單擊“登錄”按鈕。
(3)服務器接收到登錄請求后對請求參數進行校驗,查詢用戶信息,判斷用戶是否登錄成功。
(4)將登錄結果返回給用戶,如果密碼錯誤則向用戶提示密碼錯誤,如果沒有錯誤,則登錄成功。
根據以上分析創建用戶登錄時序圖,如圖9.3所示。
技術棧的選型
這里先聲明一點,如果要為公司開發一個自用的系統軟件,首先應該做的就是滿足當前的功能,以解決實際存在的問題,其次是盡可能地節約成本,降低日常的開發和維護成本,能用開源數據庫的就不用收費的數據庫。
例如,讓一個20人的小公司每年花幾千萬元買Oracle的數據庫許可證,這在國內是不大可能的事情,在滿足系統需求的前提下用開源版軟件進行開發是一個明智的選擇。
1. Spring Boot的選擇
本項目采用Spring Boot的2.3.10版本進行開發,這個版本是筆者編寫本書時最新的Spring Boot框架,筆者希望讀者能夠學習到最新版的SpringBoot的相關知識,了解新框架的功能,因此選擇這個版本進行學習。
2. JDK的選擇
目前在企業級的開發中,常用的JDK版本有兩個,分別是JDK 1.8和JDK11。Oracle官方宣布2019年1月之后發布的Oracle Java SE 8公開更新將無法用于商業或生產用途。雖然RedHat、阿里、亞馬遜這些大企業有自己的開源定制版JDK 1.8,并且為JDK 1.8提供了安全更新,但是不會再將新的功能添加到JDK 1.8中。因此本書的JDK版本選擇JDK 11。
3. 數據庫的選擇
數據庫筆者選擇了國內常用的關系型數據庫MySQL,沒有選擇PostgreSQL,是因為沒有那么多的數據分析需求和超大數據量的存儲需要,至于收費數據庫Oracle和SQL Server則不在考慮范圍內。
4. ORM框架的選擇
數據庫的ORM框架筆者選擇了國內流行的MyBatis,原因是MyBatis的使用者眾多且容易上手。而Hibernate的入門門檻更高,而且它比MyBatis更復雜。相比Hibernate,MyBatis在復雜SQL的執行上有更高的效率,且易于優化。
5. 數據庫連接池的選擇
數據庫連接在網頁應用程序中是一種重要且有限的資源。對數據庫連接
的管理能夠影響整個應用程序的伸縮性和健壯性,進而影響整個程序的性能指標,因此本項目需要一個數據庫連接池。數據庫連接池負責分配、管理和釋放數據庫連接,它允許應用程序重復使用一個現有的數據庫連接而不是重新建立一個。數據庫連接池的可選性非常多,有c3p0、DBCP、Proxool、Druid和HikariCP等。本項目使用阿里巴巴開源的Druid,它集合了c3p0、DBCP、Proxool等連接池的優點,而且還加入了日志監控,可以有效地監控DB池連接和SQL的執行情況。
6. 前后端技術的選擇
本項目沒有選擇做前后端分離,也沒有選擇使用Vue或者React來實現前端,是因為前端沒有很復雜的需求,而且筆者主要是偏向于后端開發,對前端開發工作的熟悉程度只停留在能完成簡單功能的層面,所以筆者選擇了FreeMaker作為前端的頁面引擎。
在頁面的樣式上,筆者選擇了市面上常見的樣式模板inspinia v2.8,這樣筆者就可以把所有的樣式全部集成到本項目中,需要時直接把組件拿過來用,減少了前端開發的工作量,并且樣式很好看。
本項目是一個銷售管理系統,沒有復雜的權限,因此沒有使用Shiro或者Spring Security。由于本項目中沒有復雜的權限業務,所以設計和開發工作相對來說比較簡單,沒有引入更多的數據庫(Redis)、組件(MQ、ELK)來輔助實現本系統。
JSON在Web開發中是相當常見的數據傳輸格式,需要對JSON解析并且將對象格式化為JSON數據。市場上的JSON庫有很多選擇,可以選擇使用Gson、FastJson、Jackson、Json-lib,下面分別介紹。
(1)Gson是目前Java領域功能最全的JSON解析神器,當初是應Google公司的內部需求由Google自行研發的。2008年5月公開發布的Gson應用主要有toJson與fromJson兩個轉換函數,它們無依賴,不需要額外的jar,能夠直接在JDK上運行。在使用這種對象轉換方式之前,需要先創建對象的類型及成員,然后才能將JSON字符串成功轉換成相對應的對象。需要序列化的類中只要有get和set方法,Gson就可以實現復雜類型的JSON到Bean,或Bean到JSON的轉換,可以說Gson是JSON解析的“神器”。
(2)Fastjson是一個用Java語言編寫的高性能的JSON處理器,由阿里巴巴公司開發。Fastjson沒有其他依賴,不需要額外的jar就可以直接在JDK上運行。Fastjson采用獨創的算法,將parse的速度提升到極致,超過了所有的JSON庫。
(3)Jackson是當前用得比較廣泛的Java開源框架,用來序列化和反序列化JSON。Jackson社區相對比較活躍,更新速度也比較快。從GitHub的統計來看,Jackson是最流行的JSON解析器之一,Spring MVC的默認JSON解析器便是Jackson。
(4)json-lib為應用最廣泛的JSON解析工具,它的缺點是依賴于很多第三方包,并且對于復雜類型的轉換,還存在缺陷。例如一個類里會出現另一個類的list或者map集合,json-lib從JSON到Bean的轉換就會出現問題。
json-lib在功能和性能上都不能滿足目前互聯網化的需求。
綜上所述,因為系統中沒有復雜對象的JSON轉換,所以筆者選擇國內常用且最熟悉的JSON解析工具——Fastjson。
Apache提供了眾多的commons工具包,其中lang 3包最受歡迎。lang 3是Apache Commons團隊發布的工具包,要求JDK版本在1.5以上,相對于lang來說其完全支持Java 5的特性,廢除了一些舊的API。lang 3版本無法兼容舊版本,于是為了避免沖突改名為lang 3。在本項目中筆者使用Apache的lang 3包和Google的Guava作為工具類包,以盡可能地減少各種依賴項目。
項目開發完成后,將其打成一個jar包,只需要安裝Java的環境和MySQL數據庫就可以直接運行起來。
7. 構建工具的選擇
本項目使用Maven作為依賴的管理和構建工具,之所以沒有使用Gradle,是因為相較于Maven,筆者認為Gradle的優勢并不明顯,為了項目的易用性和穩固性,筆者選擇使用更加熟悉的Maven。
8. 代碼規范
本項目中使用阿里巴巴的代碼規范指導開發,盡量遵守相關的規范,在命名方式上選擇使用駝峰的方式,數據庫的設計規范如下:
(1)數據庫的表名采用26個英文字母(區分大小寫)和0~9的自然數加上下劃線“_”組成;命名簡潔、明確(長度盡量不能超過30個字符);例如,可以使用user、sys或log給數據庫中的表名加個前綴,方便對同一類型的表進行統一管理;表命名全部使用下劃線來分隔并且全部使用小寫字母。
(2)可以使用表前綴user_有效讓相同關系的表一起顯示。
(3)每個表中必須有自增主鍵和create_time(默認系統時間),表與表之間的相關聯字段名稱要求盡可能相同。
(4)用盡量少的存儲空間來存儲一個字段的數據。例如,能使用int就不要使用varchar或char,能用varchar(16)就不要使用varchar(256)。IP地址最好使用int類型,固定長度的類型最好使用char(如郵政編碼),能使用tinyint就不要使用smallint或int;最好給每個字段設置一個默認值,并且不要設置為null。
(5)為每個表創建一個主鍵索引。
(6)少用text類型(盡量使用varchar代替text字段)。
(7)拒絕大SQL語句、大事務和大批量操作。
(8)不在數據庫中做運算,CPU計算務必移至業務層。
(9)控制列數量(字段要少而精,字段數建議在20個以內);平衡范式與冗余(有時在追求查詢效率的提升時往往需要在表中設計冗余字段,因而不符合數據可設計范式。強調數據庫設計范式能提升數據庫的擴展性,但同時會降低數據庫的查詢效率)。
9. 版本管理
本項目的代碼使用Git進行管理,使用Git提交的Message格式為type(scope): subject,其中,type為提交的類型,有以下5種:
feat:新功能開發;
fix:修補Bug;
docs:新增/修改文檔;
refactor:重構代碼;
test:測試用例。
scope為當前提交的影響范圍,即哪個項目下哪一個模塊的變動,subject提交的就是具體的變動信息,應盡可能詳細。
使用Git進行功能開發時的分支管理有以下幾個:
master:Git的默認主分支。
stable:穩定分支,替代master,主要用于版本發布。
develop:日常開發分支,該分支保存開發的最新代碼。
feature:具體的功能開發分支,只與develop分支交互。
release:該分支可以認為是stable分支的未測試版。例如,某一期的功能全部開發完成,那么就將develop分支與release分支合并,測試沒有問題,到了發布日期就將其與stable分支合并,然后進行發布。
feature-name:個人功能開發分支,個人在功能開發完成后把個人分支與feature分支合并。