ORM (Object Relational Mapping):建立 Java 對象模型與關係數據表的元數據映射,操作對象即操作數據,消除手寫 JDBC/SQL 樣板代碼。
Hibernate 特點:
| 組件 | 接口/類 | 職責 | 生命周期 |
|---|---|---|---|
| 配置管理 | Configuration | 讀取 cfg.xml、映射文件,構建 SessionFactory | 啟動一次 |
| 會話工廠 | SessionFactory | 線程安全、重量級、產生 Session,緩存元數據/二級緩存 | 應用級單例 |
| 會話 | Session | 線程不安全、輕量級、CRUD、事務邊界、一級緩存 | 請求級/事務級 |
| 查詢 | Query/Criteria | HQL/Criteria/SQL 查詢,參數綁定、分頁、投影 | Session 內 |
| 事務 | Transaction | 統一 JDBC/JTA 事務 API,commit/rollback | 業務邊界 |
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.6.15.Final</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>5.0.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.9</version>
</dependency>
</dependencies>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"https://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- JDBC 連接 -->
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_demo?useSSL=false&serverTimezone=UTC</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<!-- 連接池 HikariCP -->
<property name="hibernate.hikari.dataSourceClassName">com.mysql.cj.jdbc.MysqlDataSource</property>
<property name="hibernate.hikari.maximumPoolSize">10</property>
<!-- 方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
<!-- SQL 輸出 -->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<!-- DDL 自動 (僅開發) -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 映射文件 -->
<mapping resource="com/demo/entity/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.demo.entity">
<class name="User" table="t_user">
<id name="id" column="id">
<generator class="native"/>
</id>
<property name="username" column="username"/>
<property name="password" column="password"/>
<property name="email" column="email"/>
</class>
</hibernate-mapping>
package com.demo.entity;
public class User {
private Long id;
private String username;
private String password;
private String email;
// 構造器、getter/setter、toString 省略
}
public class HibernateDemo {
private static SessionFactory factory;
static {
Configuration cfg = new Configuration().configure(); // 讀取 hibernate.cfg.xml
factory = cfg.buildSessionFactory();
}
public static void main(String[] args) {
// 1. 新增
saveUser();
// 2. 查詢
User u = getUser(1L);
// 3. 修改
if (u != null) { u.setEmail("new@qq.com"); updateUser(u); }
// 4. 刪除
deleteUser(1L);
}
static void saveUser() {
Session session = factory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
User user = new User(); user.setUsername("alice"); user.setPassword("123"); user.setEmail("alice@qq.com");
session.save(user); // 持久化,ID 回寫
tx.commit();
System.out.println("保存成功,ID=" + user.getId());
} catch (Exception e) { if (tx!=null) tx.rollback(); e.printStackTrace(); }
finally { session.close(); }
}
static User getUser(Long id) {
Session session = factory.openSession();
try {
User user = session.get(User.class, id); // 走一級緩存/二級緩存/DB
System.out.println("查詢: " + user);
return user;
} finally { session.close(); }
}
static void updateUser(User user) {
Session session = factory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
session.update(user); // 合併游離對象
tx.commit();
System.out.println("修改成功");
} catch (Exception e) { if (tx!=null) tx.rollback(); e.printStackTrace(); }
finally { session.close(); }
}
static void deleteUser(Long id) {
Session session = factory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
User user = session.get(User.class, id);
if (user != null) { session.delete(user); }
tx.commit();
System.out.println("刪除成功");
} catch (Exception e) { if (tx!=null) tx.rollback(); e.printStackTrace(); }
finally { session.close(); }
}
}
LazyInitializationException,解決:Hibernate.initialize()、@BatchSize、DTO 投影。hbm2ddl.auto=create 生產嚴禁,會刪表重建。Session 非線程安全,請勿作為實例變量共享,請求級打開關閉。StatelessSession 或 scroll() 游標,避免一級緩存 OOM。FETCH JOIN、@BatchSize、subselect fetching。Hibernate 以 Session 為核心,映射元數據為橋樑,脏檢查為引擎,實現了從對象圖到關係表的無縫映射。掌握 Configuration → SessionFactory → Session → Transaction 四大組件協作、對象三態流轉、CRUD 模板代碼、脏檢查與延遲加載機制,即可駕輕就熟地構建企業級持久層。進階之路:二級緩存 (Redis/Ehcache)、CriteriaBuilder 動態查詢、Envers 審計、多租戶、響應式 (R2DBC) 集成。