Hibernate 根據對象與 Session 關聯程度,將對象劃分為三種狀態,理解狀態轉換是掌握 ORM 操作的關鍵。
| 狀態 | 特徵 | 典型場景 |
|---|---|---|
| 瞬時態 | new 創建,無 ID,無 Session 管理,無數據庫記錄對應 | new User() 剛創建 |
| 持久態 | 關聯 Session,有 ID(數據庫主鍵),Session 追蹤變更,事務提交自動同步 DB | session.save(user)、session.get(User.class, id) |
| 游離態 | 曾持久,現脫離 Session 管理,有 ID 但 Session 無法感知變更 | session.close()、session.evict(obj) 後 |
瞬時態 ──save()/saveOrUpdate()──▶ 持久態 ▲ │ │ │ │ delete() │ evict()/clear()/close() │ ▼ ▼ └────── delete() ◀─────── 游離態 ◀── update()/saveOrUpdate()
save()、saveOrUpdate()、get()、load()delete()(數據庫記錄刪除,對象變瞬時)evict(obj)(移除特定)、clear()(清空)、close()(關閉 Session)update()、saveOrUpdate()(重新關聯新 Session)delete()| 特性 | get() | load() |
|---|---|---|
| 查無數據 | 返回 null | 拋 ObjectNotFoundException |
| 加載策略 | 立即查詢,發 SQL | 延遲加載,返回代理對象,首次訪問非 ID 屬性才發 SQL |
| 性能 | 確定存在用 get | 確定存在、僅需 ID 關聯時用 load |
原理:load() 利用 CGLIB 動態代理,代理對象僅含 ID,屬性訪問時觸發攔截器查詢數據庫。
get(),業務邏輯需判空。load() 避免多餘查詢。