首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Hibernate 核心詳解:Session 生命周期管理與持久化類 (POJO) 設計規範

     編輯:Java 相關知識

Session:持久化操作的核心入口

org.hibernate.Session 是 Hibernate 與數據庫交互的核心接口,代表一個**短生命周期**、**單線程**、**輕量級**的工作單元。它封裝了 JDBC Connection,管理一級緩存,提供 CRUD、查詢、事務控制等核心 API。

三大對象狀態與轉換

理解狀態轉換是掌握 Session 的關鍵:

  1. 瞬時態:new Entity() 創建,無 ID,無關聯 Session,不在數據庫中。GC 可回收。
  2. 持久態:關聯 Session,有 ID,對應數據庫記錄。修改自動同步到數據庫 (脏檢查),無需調用 update。
  3. 游離態:Session 關閉/清理/驅逐後,原持久態對象變為游離態。有 ID,但無 Session 關聯,修改不會自動同步。

狀態轉換圖:

瞬時態 --save()/persist()--> 持久態
持久態 --delete()/remove()--> 瞬時態 (數據庫記錄刪除)
持久態 --close()/evict()/clear()--> 游離態
游離態 --update()/merge()/saveOrUpdate()--> 持久態
游離態 --lock()--> 持久態 (僅重新關聯,不檢查數據庫)

標準 Session 使用模板

Session session = sessionFactory.openSession();
Transaction tx = null;
try {
    tx = session.beginTransaction();
    
    // 1. 保存
    User user = new User("John", "john@example.com");
    session.persist(user); // 或 save()
    
    // 2. 查詢 (自動加入一級緩存)
    User loaded = session.get(User.class, user.getId());
    
    // 3. 修改 (無需調用 update,提交事務時自動脏檢查同步)
    loaded.setEmail("new@example.com");
    
    // 4. 刪除
    // session.remove(loaded);
    
    tx.commit();
} catch (Exception e) {
    if (tx != null) tx.rollback();
    e.printStackTrace();
} finally {
    session.close(); // 必須關閉,釋放連接、清理一級緩存
}

關鍵注意事項

  • 線程不安全:Session 單線程使用,**嚴禁**作為實例變量共享 (如 Servlet 成員變量)。
  • 一級緩存作用域:Session 級別,事務提交或關閉時清理。同一 Session 內多次 get/load 同 ID 只發 1 條 SQL。
  • load() vs get():load() 返回代理對象,不存在拋異常 (延遲加載);get() 立即查庫,不存在返回 null。
  • 脏檢查機制:提交事務時比較對象快照,僅更新修改字段,極大減少 SQL。

持久化類 (POJO) 設計規範

Hibernate 通過映射元數據 (註解/XML) 將 POJO 與數據庫表關聯。遵循 POJO 規範可確保框架正常運行 (代理、反射、序列化)。

硬性規範 (JPA/Hibernate 強制)

  1. 無參構造函數:public/protected 可見性,供反射實例化與代理創建。
  2. 標識屬性:@Id 標註主鍵字段,建議使用包裝類型 (Long, String) 以便判斷是否為新對象 (null 表示瞬時態)。
  3. 非 final 類/方法:允許 Hibernate 生成字節碼增強代理 (延遲加載、脏檢查)。

最佳實踐規範

  1. 字段 private,提供標準 Getter/Setter (字段訪問策略下可省略)。
  2. 實現 Serializable (支持集群/緩存傳遞)。
  3. 覆寫 equals() 和 hashCode():基於**業務鍵** (非 ID,因 ID 可能未生成) 或 **ID + 類型**,保證 Set 集合去重正確。
  4. 集合屬性初始化:private Set roles = new HashSet<>(); 避免空指針。
  5. 使用 @Entity, @Table, @Column 等註解完成映射,或編寫 .hbm.xml。

標準 POJO 範例

@Entity
@Table(name = "t_employee")
public class Employee implements Serializable {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "first_name", length = 50, nullable = false)
    private String firstName;
    
    @Column(name = "last_name", length = 50)
    private String lastName;
    
    @Column(name = "salary", precision = 10, scale = 2)
    private BigDecimal salary;
    
    @Version // 樂觀鎖版本號
    private Integer version;
    
    // 無參構造函數
    public Employee() {}
    
    // 業務構造函數
    public Employee(String firstName, String lastName, BigDecimal salary) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.salary = salary;
    }
    
    // Getter/Setter 省略...
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Employee)) return false;
        Employee that = (Employee) o;
        return Objects.equals(firstName, that.firstName) && 
               Objects.equals(lastName, that.lastName);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(firstName, lastName);
    }
}

總結

Session 是 Hibernate 工作單元的核心,掌握「三態轉換」、「標準模板」、「脏檢查」與「線程安全」是高效使用的基石。持久化類遵循 POJO 規範,配合合理的映射策略,能充分發揮 ORM 的生產力優勢。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved