Java開發規範-細則.md

一般情況,應當儘量遵守下面各規則,特殊情況除外,如有必要需要評審! 因爲約定熟成, 統一、標準的操作, 才能自動化!

一、數據庫表的設計

各字段應該使用什麼類型,什麼精度?

  • 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!

四、關於測試

複雜模塊,儘量編寫單元測試

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章