Hibernate 映射核心三要素
- 實體類:POJO,承載業務數據
- 映射文件:
.hbm.xml,定義對象-關係映射規則
- 配置文件:
hibernate.cfg.xml,數據源、方言、映射註冊
實體類規範
package com.example.model;
import java.util.Date;
public class User {
private Long id; // 主鍵,包裝類型支持 null
private String name;
private String password;
private Date createTime;
private Date expireTime;
// 無參構造器(Hibernate 實例化必需)
public User() {}
// 全屬性構造器(可選,業務便利)
public User(String name, String password) {
this.name = name;
this.password = password;
}
// Getter/Setter(屬性訪問策略默認)
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
// ... 其他屬性同理
// 建議覆寫 equals/hashCode(基於業務鍵或 ID)
@Override
public boolean equals(Object o) { ... }
@Override
public int hashCode() { ... }
}
關鍵約定:無參構造器、非 final 類、屬性私有+Getter/Setter、主鍵用包裝類型。
映射文件 User.hbm.xml 詳解
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.example.model"> <!-- 包前綴,簡化類名 -->
<class name="User" table="t_user"> <!-- 實體類映射表 -->
<!-- 主鍵映射 -->
<id name="id" column="user_id" type="java.lang.Long">
<generator class="native"/> <!-- 主鍵生成策略 -->
</id>
<!-- 普通屬性映射 -->
<property name="name" column="user_name" type="string" length="50" not-null="true"/>
<property name="password" column="pwd" type="string" length="100" not-null="true"/>
<property name="createTime" column="create_time" type="timestamp" not-null="true"/>
<property name="expireTime" column="expire_time" type="timestamp"/>
</class>
</hibernate-mapping>
主鍵生成策略選型指南
| 策略 | 適用數據庫 | 特點 | 適用場景 |
native | MySQL/PostgreSQL/Oracle/SQL Server | 自適應:identity/sequence/hilo | 跨數據庫項目,推薦默認 |
identity | MySQL/SQL Server/DB2 | 自增列,插入時生成 | MySQL 自增主鍵 |
sequence | Oracle/PostgreSQL/DB2 | 序列對象,需預創建 | Oracle 主鍵 |
uuid / uuid.hex | 所有 | 128bit UUID,32位十六進制,分佈式友好 | 分佈式系統、無序主鍵 |
assigned | 所有 | 手動分配(業務主鍵) | 業務含義主鍵(如訂單號) |
foreign | 所有 | 關聯對象主鍵(一對一共享主鍵) | 一對一關聯 |
<!-- sequence 完整配置示例 -->
<id name="id" column="user_id">
<generator class="sequence">
<param name="sequence">seq_user_id</param>
</generator>
</id>
屬性映射屬性詳解
| 屬性 | 作用 | 常用值 |
name | 實體類屬性名 | Java 屬性名 |
column | 數據庫列名 | 默認同屬性名,建議顯式指定 |
type | Hibernate 類型 | string, long, integer, timestamp, date, boolean, text, blob, clob... |
length | 字符串長度 | DDL 生成參考,如 VARCHAR(50) |
not-null | 非空約束 | true/false,DDL 生成參考 |
unique | 唯一約束 | true/false,DDL 生成參考 |
insert/update | 是否包含在 INSERT/UPDATE | true/false,如創建時間僅 insert=true, update=false |
formula | 衍生屬性 SQL 片段 | (SELECT COUNT(*) FROM t_order WHERE user_id = id) |
Hibernate 核心配置 hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"https://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 數據源配置 -->
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=Asia/Shanghai</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<!-- 方言:SQL 生成適配 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
<!-- 連接池 (內置簡易池,生產建議 HikariCP) -->
<property name="hibernate.connection.pool_size">10</property>
<!-- 顯示 SQL -->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.use_sql_comments">true</property>
<!-- 自動 DDL (開發環境) -->
<property name="hibernate.hbm2ddl.auto">update</property> <!-- validate/update/create/create-drop -->
<!-- 緩存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
<!-- 映射文件註冊 -->
<mapping resource="com/example/model/User.hbm.xml"/>
<mapping resource="com/example/model/Order.hbm.xml"/>
</session-factory>
</hibernate-configuration>
SessionFactory 構建與 Session 使用
// 單例構建 SessionFactory (重量級,線程安全)
Configuration cfg = new Configuration().configure(); // 加載 hibernate.cfg.xml
SessionFactory sf = cfg.buildSessionFactory();
// 輕量級 Session (非線程安全,請求級/事務級)
Session session = sf.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
// CRUD 操作
User user = new User("張三", "123");
session.save(user); // 持久化
User loaded = session.get(User.class, user.getId()); // 查詢
loaded.setName("李四"); // 髒檢查自動更新
session.delete(loaded); // 刪除
tx.commit();
} catch (Exception e) {
if (tx != null) tx.rollback();
throw e;
} finally {
session.close(); // 歸還連接
}
常見映射類型對照表
| Java 類型 | Hibernate 類型 | 數據庫類型示例 |
| String | string / text | VARCHAR / TEXT / CLOB |
| Long/long | long | BIGINT |
| Integer/int | integer | INT |
| Double/double | double | DOUBLE |
| BigDecimal | big_decimal | DECIMAL(19,2) |
| java.util.Date | timestamp / date / time | DATETIME / DATE / TIME |
| java.time.LocalDateTime | local_date_time | DATETIME |
| byte[] | binary / blob | VARBINARY / BLOB |
| Boolean/boolean | boolean / yes_no / true_false | BIT / CHAR(1) / VARCHAR(5) |
自動 DDL 策略對比
| 策略 | 行為 | 適用環境 |
validate | 僅校驗映射與數據庫一致,不修改 | 生產 |
update | 自動新增表/列,不刪除 | 開發/測試 |
create | 啟動時刪除重建 | 測試/單元測試 |
create-drop | 啟動建立,關閉刪除 | 單元測試 |
none | 不操作 | 生產(手動管理 DDL) |
最佳實踐總結
- 顯式指定 column、type、length,避免默認推斷差異
- 主鍵優先用 native/identity/sequence,分佈式用 uuid
- 映射文件按模塊組織,
hibernate-mapping package 簡化類名
- 生產環境 hbm2ddl.auto=validate,DDL 由遷腳本管理
- 連接池替換為 HikariCP,配置
hibernate.connection.provider_class
- 開啟 SQL 格式化輸出,開發調試期
show_sql=true, format_sql=true
- 二級緩存謹慎啟用,只讀/低寫入頻率實體優先
總結
Hibernate 基礎映射由實體類規範、.hbm.xml 映射定義、hibernate.cfg.xml 核心配置三部分構成。掌握主鍵生成策略選型、屬性映射屬性、類型對照、SessionFactory/Session 使用模式、DDL 自動策略,能快速構建穩健的 ORM 基礎設施。原則:顯式優於隱式、生產嚴格校驗、連接池專業化、緩存按需啟用。