一般情況,應當儘量遵守下面各規則,特殊情況除外,如有必要需要評審! 因爲約定熟成, 統一、標準的操作, 才能自動化!
一、數據庫表的設計
各字段應該使用什麼類型,什麼精度?
- id 字段是使用 int、bigint、char還是varchar?
一般情況下建議使用 int, 而且是自動遞增
int有11位,可以存儲42憶數據,最大值是21億左右,範圍是-231到231-1,即 -2147483648~2147483647, 而 bigint 是 -263到263-1, 即從-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
顯然 bigint 就過於龐大, 一般來說 int 也是足夠,但是如果不夠, 那麼也可以考慮使用bigint存儲。 另外, 一般情況下, 當一張表數據過千萬,那麼應該考慮分表分庫
- 對於bool或狀態字段,數據庫中使用什麼進行存儲? int、tinyint、enum、char還是 varchar?
數據庫統一 char, java統一 string, 這樣可以減少出錯的可能! 後端代碼不做轉換, 全部由前端展示的時候進行轉換!!
對於bool,java中儘量不使用 enum 做展示,如果每一個bool 都給創建一個bool, 其實也是很麻煩的。我們僅僅使用靜態常量表示即可。
- 日期字段需要區分是日期還是時間, 還是同時包括日期+時間,然後選擇對於的數據類型:
日期字段以 _date結尾, 數據庫字段的存儲類型爲 date
日期字段以 _time 結尾, 數據庫字段的存儲類型爲 time
日期+時間字段以 _time 結尾, 數據庫字段的存儲類型爲 datetime , 不應該使用 timestamp,或者long( long可讀性差)
如何冗餘關聯字段?
比如, 某表關聯的人員字段是存id 還是存name?
一般情況下,id 肯定是需要存的,name 字段則不一定, 如果需要經常做展示,那麼可以使用 name 做冗餘。 但是缺點是需要考慮在更新人員信息的時候,同步更新這個冗餘字段。
如果不需要做展示,那麼不需要冗餘 name。
name 還是code?
一般情況下,name允許重複, code不允許重複,code是唯一的。所有,一般可以通過code做表關聯,name做冗餘展示。
字段是否需要默認值?如何設置?
所有字段都儘量設置默認值,一般情況下,數值型字段默認值爲0,字符串默認'' (即空字符串)。
如果有 create_time、update_time字段,那麼 create_time、update_time 應該設置爲 CURRENT_TIMESTAMP, 同時update_time 應該設置爲 ON UPDATE CURRENT_TIMESTAMP:
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最後修改時間'
(使用數據庫時間, 記得保持 數據庫服務器時間和應用服務器時間同步)
字段長度
name類型字段一般不能超過25個漢字、64字符
code 由業務而定
description、remark描述字段255個漢字
排序
查詢返回數據,默認按照id排序、 或者創建時間、 最後修改時間、name
通用的建表語句:
CREATE TABLE `module_business` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵', `name` varchar(255) NOT NULL DEFAULT '' COMMENT 'xxx名稱', -- 業務字段 `deleted` char(4) NOT NULL DEFAULT 'n' COMMENT '邏輯刪除標誌: 已邏輯刪除: y; 正常狀態: n; ', `status` char(16) NOT NULL DEFAULT 'draft' COMMENT '狀態: draft 草稿;committed 已提交;audited 已審覈;rejected 已駁回', `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '備註', `create_by` int(11) NOT NULL DEFAULT 0 COMMENT '創建人', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間', `update_by` int(11) NOT NULL DEFAULT 0 COMMENT '最後修改人', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最後修改時間', PRIMARY KEY (`id`) ) ENGINE=InnoDB COMMENT='xxx業務對象';
二、命名
通用數據庫字段的命名, 下劃線分隔,全部小寫
主鍵:id 狀態:status 備註:remark 創建時間:create_time 創建人:create_by 最後修改時間:update_time 最後修改人:update_by
長格式還是短格式?
比如 app_agreement表, 有人將id字段命名爲agreement_id, 有人 id, 各有優缺點。這裏我們強制使用id!簡單明瞭!
對於方法名也是如此,方法命名 儘量一個動詞搞定!簡化! 儘量不需要方法名中添加實體對象,比如"修改":
正例:update()
反例:updateAppAgreement()
因爲當前類名已經表明了是AppAgreement, 比如AppAgreementController、AppAgreementService , 當然, 這個不是強制性的,如果當前方法不是直接操作對象,跟類名沒有關係,那麼就還是可以在方法名後加上對象名稱
通用的方法命名要統一
應該儘量統一使用通用的方法動詞,而不是 奇奇怪怪的動詞
新增
推薦:insert add
避免:save
刪除
推薦:delete
避免:remove
修改
推薦:update
避免:setXxx modify
查單個
推薦:getById getOne
避免:select query find
列表查詢:list
分頁查詢:page
提交:submit
審覈:audit
配置:config
所有術語需要整個項目保持統一
需要保證一個單詞、漢語詞語在整個項目中含義一致, 不要出現不一致
名詞統一:
系統: sys、system
用戶: user
產品: product
訂單: order
消息: msg、message
廣告: ad
商品: goods
地區: area
協議、同意書: agreement
...
動詞統一:
編輯: edit
配置: config
管理: manage
統計: stat
推送: push
...
名字是使用全稱還是簡稱?
一般情況下, 常用的術語可以使用簡寫、縮寫, 用得少的不簡寫(框架自帶的除外)
模塊命名可以簡寫, 表、服務、接口等命名不要簡寫
非常常用的地方、局部變量可以使用簡寫
三、項目風格
項目目錄結構風格
集中還是分散?說明:
- 集中: 整個微服務只創建一個controller、一個service、一個dao、一個entity 目錄, 所有的表、模塊的controller都集中到一起,service/dao/entity 都依此類推
- 分散: 在每個表下面創建各自的 controller、service、dao、entity 目錄
- 對於簡單的項目,深度或廣度都無所謂,都不要緊。
對於大型、複雜項目,儘量還是按照模塊來。應該在每個模塊下面創建各自的 controller、service、dao、entity 目錄
不要出現奇怪的模塊目錄結構
每個模塊目錄結構如下:
controller、service、dao、entity、config、constant、util, 除此之外,儘量不應該出現其他目錄。
注: 如果沒有對應的類,可以不用創建那個目錄。
需要Dto/Vo/Bo/Po/Param 嗎
前端調用後端方法的時候,後端方法的接收參數需要封裝嗎? controller調用service、service調用dao 需要封裝參數嗎?需要封裝返回值嗎?
儘量還是不用Dto/Vo/Bo, 直接實體類即可。
當然如果,如果實體類滿足不了業務需要,應當進行封裝,統一使用 xxxDto
提煉公共組件
公共組件,能夠提煉到公告地方的, 一定要提煉!! 可以減少臃腫,儘量實現通用
比如,很多地方都會使用到bool常量,如果我們每個模塊都定義一遍,會顯得非常的重複,這樣的非常常見的、通用的工具、靜態類、枚舉,應當放到公共組件
RESTful 風格
- 完全的 RESTful 還是部分的? 儘量使用完全的RESTful!
- 但如果http方法衝突,那麼不得已,url中也可以使用動詞
- controller 方法參數是否需要封裝? 不需要json封裝,直接傳遞所需要的數據即可
- controller 方法返回什麼? 返回json,完全的 json格式。 統一的字段: code、 msg、 data。 統一使用工具類:R
- 是否需要返回值狀態碼還是通過返回值的code 來表示?code需要儘量模擬 http協議對狀態碼的規定,如下:
操作成功:200
系統異常:500
網關異常:503
參數/客戶端錯誤: 400
找不到資源: 404
Swagger風格
Swagger還是其他? 暫定
保留swagger 基本註解: @Api,但是不需要很詳細
否則swagger 會導致代碼臃腫,侵入太大
註釋風格
簡單的方法,不需要寫,或者少寫。 複雜方法,必須要寫
寫在 service 接口上還是 接口的實現類impl上?寫在接口上即可,其他地方可以不用寫.
通用字段處理
create_time create_by update_time update_by 應該自動處理。
如果沒有業務屬性, 可以不需要這些字段; 但如果有,那麼就需要維護好
可以通過攔截器或框架來做比較好,不要手動維護,造成代碼囉嗦臃腫。
對於create_time、update_time 時間字段,可以由數據庫來維護
參數校驗
普通的操作,參數校驗可選,前端校驗一下即可
重要的操作,前後端都需要做參數校驗,
後端如何校驗? 使用統一的註解,通過框架完成,而儘量不要手動進行校驗
項目依賴管理
pom.xml 依賴應該統一由一個人管理,其他人只讀不能修改; 統一一個地方維護
如果確實需要修改,應該由負責人確定,然後負責人來實施
pom.xml 的依賴應當儘量的簡潔,不應該過多的重複
如何認證、鑑權?
註釋風格, 統一處理. jwt token + redis
異常處理
不要到處 try catch,代碼中儘量不出現異常處理!
統一到 ExceptionHandler 進行處理
如何分頁
手動? pagehelper, 還是mybatis plus提供的?
必須使用mybatis框架自帶的!
編碼格式
數據庫字符集 utf8mb4
數據庫排序規則 utf8mb4_general_ci
我們僅僅數據庫的字符集、排序規則 即可, 不需要給表、字段單獨設置字符集、排序規則, 以免引起不一致。 儘量保持統一
項目的代碼源文件,應該全部 utf8
maven依賴如何管理版本號,何時進行升級?
儘量不升級,如果有必要,則:
第三方的依賴: 統一升級;
自己的項目的升級: 按照項目、業務發展需要
如何記錄日誌?
Controller層的方法不用寫任何日誌,通過攔截器實現
serviceimpl層的方法, 按照業務需要寫日誌
dao/mapper/util層,及其他層的方法不用寫任何日誌
分支管理
開發: develop
測試: release
發佈: main
大小寫
儘量全部使用小寫,方便閱讀!
不管是表名、字段名、字段值、
包名、 變量名、 常量值 等等
其他
Mybatis plus 還是Mybatis?統一使用 Mybatis plus,可以減少sql編寫。dao層儘量不寫sql,因爲難以維護, 儘量使用mybatis-plus提供的方法
mybatis plus2 還是3?3 !
所以實體對象使用lombok
fastjson 還是 jackson? 統一 fastjson
java.util.Date 還是 java.time.LocalDate ? 對於數據庫字段,還是統一 java.util.Date , 因爲這個兼容性好,工具生成的代碼都是這個格式。
所有實體類統一繼承基礎實體類(跟隨框架)
避免空值: controller、service、dao 的方法一律不能返回空值
使用靜態常量還是枚舉? 儘量減少枚舉,因爲可讀性比較差
儘量使用標準組件、統一化, 如果有bug,那麼也只是修改一個地方即可
儘量少寫代碼,沒有代碼自然不會有bug!
四、關於測試
複雜模塊,儘量編寫單元測試