在大型、既有、多系統共用的資料庫上落地 Hibernate/JPA,純理論知識遠不夠。以下十大心法源自實戰血淚,助你避開坑洞、駕馭複雜度。
1. 與 DBA 結盟:你的成敗在他們手中
- DBA 能讓專案失敗 (鎖表、拒權限、改參數),卻不能單獨讓專案成功
- DBA 擁有資料庫深層洞察:索引策略、執行計畫、歷史坑點
- 實例:一個 DBA 建議的 SQL 函數替代複雜關聯查詢,配合
@Formula 映射,效能提升 10 倍
2. 從 Day 1 強制命名規範
- 表名、欄位、實體、屬性、布林值 (Y/N vs 0/1)、外鍵、索引命名 — 全部標準化
- 工具自動生成的命名往往不可讀,務必人工審核
- 統一規範 = 降低認知負載 + 避免映射錯誤 + 利於代碼審查
3. 不要映射所有欄位
- 既有資料庫常有數十甚至上百欄位,大多業務不關心
- 只映射需要的欄位,減少記憶體、網路、快取開銷
- 工具全表映射是反模式
4. 讓資料庫做資料庫擅長的事
- 統計、聚合、複雜關聯運算 → 資料庫函數/預存程序/視圖
- 用
@Formula 將資料庫計算欄位映射為實體唯讀屬性
- 領域模型保持乾淨,效能交給資料庫引擎
5. 增量建模:切分資料庫、分批映射
- 一次映射全庫 = 巨大工程 + 使用者看不見進度 + 必返工
- 按業務邊界 (Bounded Context) 切分,每次迭代只映射當前故事需要的表
- 演進式設計:映射隨需求成長,而非預先大爆炸
6. 時刻警惕 Trigger (觸發器)
- Trigger 隱形執行邏輯,導致 Hibernate 狀態不一致 (版本號未增、快取未失效)
- 資料遺失、重複、異常更新常由 Trigger 引發
- 原則:能用 Hibernate 事件/攔截器/資料庫約束替代 Trigger 就替代
7. 拒絕自動生成模型:手寫即理解
- 工具 (Dali 等) 生成的模型往往包含 Bug、多餘關聯、錯誤型別
- 手寫 Entity/Mapping 強迫你理解每個欄位、關聯、約束
- 時間成本極低,回報極高
8. 盡量使用 Named Query
- 集中管理 HQL/SQL,便於 DBA 調優、代碼審查、重用
- 啟動期驗證語法,運行期不會出現拼寫錯誤
- 定義於
@NamedQuery 或 .hbm.xml,而非散落業務代碼
9. 管理預期:框架不是銀彈
- 團隊若以為「用了 Hibernate 就不需要 DBA/資料庫優化/SQL 知識」,專案必失敗
- 明確溝通:Hibernate 解決什麼問題 (物件持久化、狀態管理),不解決什麼 (糟糕 SQL、錯誤索引、資料庫設計缺陷)
10. 擁抱富域模型
- 貧血模型 只是資料容器,業務邏輯散落 Service 層,難測試、難維護
- 將業務行為 (驗證、狀態流轉、計算) 封裝進 Entity
- Hibernate/JPA 支援私有欄位存取、嵌入式物件、領域事件 — 充分利用
- 富模型 = 程式碼重用 + 測試友善 + 表達力強
結語
這十條心法無關 API 語法,全關乎「如何在真實世界駕馭 ORM」。技術容易,工程難;理解業務、尊重資料庫、紀律建模,才是 Hibernate/JPA 專案成功的鑰匙。