Hibernate 4 教程:从入门到实践
Hibernate 是一个开源的 ORM(Object-Relational Mapping,对象关系映射)框架,它极大地简化了 Java 应用程序与数据库之间的交互,通过 Hibernate,您可以用面向对象的方式来操作数据库,而无需编写大量的 JDBC 代码。

目录
-
第一部分:环境准备与项目搭建
- 1 前提条件
- 2 创建 Maven 项目
- 3 添加 Hibernate 4 和 MySQL 依赖
- 4 项目结构
-
第二部分:Hibernate 核心配置
- 1 数据库连接配置 (
hibernate.cfg.xml) - 2 实体类映射配置 (
*.hbm.xml) - 3 整合配置:主配置文件引用映射文件
- 1 数据库连接配置 (
-
第三部分:编写第一个 Hibernate 程序
- 1 创建实体类
- 2 创建映射文件
- 3 创建工具类(获取 SessionFactory)
- 4 编写测试代码(保存一个对象)
-
第四部分:Hibernate 核心 API 详解
- 1
Configuration: 配置加载 - 2
ServiceRegistry: 服务注册中心 (Hibernate 4 核心变化) - 3
SessionFactory: 线程安全的工厂 - 4
Session: 轻量级线程不安全的“非自动提交”连接 - 5
Transaction: 事务管理 - 6
Query和Criteria: 查询接口
- 1
-
第五部分:CRUD 操作
- 1 创建 -
save()/persist() - 2 读取 -
get()/load() - 3 更新 -
update() - 4 删除 -
delete() - 5 HQL 查询示例
- 1 创建 -
-
第六部分:进阶主题
- 1 关系映射(一对多)
- 2 注解方式配置(
@Entity,@Id等)
第一部分:环境准备与项目搭建
1 前提条件
- Java Development Kit (JDK): 推荐 JDK 7 或 8。
- IDE: IntelliJ IDEA 或 Eclipse。
- 构建工具: Maven 或 Gradle,本教程使用 Maven。
- 数据库: MySQL 5.7 或更高版本。
- MySQL JDBC 驱动:
mysql-connector-java。
2 创建 Maven 项目
在您的 IDE 中,创建一个新的 Maven 项目,如果您使用命令行,可以执行:
mvn archetype:generate -DgroupId=com.example -DartifactId=hibernate4-tutorial -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
3 添加 Hibernate 4 和 MySQL 依赖
打开 pom.xml 文件,添加以下依赖:
<dependencies>
<!-- Hibernate 4 Core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.11.Final</version> <!-- 这是一个稳定的 Hibernate 4 最终版本 -->
</dependency>
<!-- MySQL Connector/J -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version> <!-- 请根据您的 MySQL 版本选择合适的驱动 -->
</dependency>
<!-- JPA API (Hibernate 实现了 JPA 标准) -->
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.2.Final</version>
</dependency>
</dependencies>
4 项目结构
一个典型的 Maven 项目结构如下:
hibernate4-tutorial
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── example
│ │ │ ├── entity
│ │ │ │ └── User.java
│ │ │ ├── util
│ │ │ │ └── HibernateUtil.java
│ │ │ └── App.java
│ │ └── resources
│ │ ├── hibernate.cfg.xml
│ │ └── com
│ │ └── example
│ │ └── entity
│ │ └── User.hbm.xml
│ └── test
│ └── java
└── pom.xml
第二部分:Hibernate 核心配置
Hibernate 使用 XML 文件来配置数据库连接和映射信息。
1 数据库连接配置 (hibernate.cfg.xml)
在 src/main/resources 目录下创建 hibernate.cfg.xml 文件,这是 Hibernate 的主配置文件。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 1. Database connection settings -->
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_db?useSSL=false&serverTimezone=UTC</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">your_password</property>
<!-- 2. Dialect: This makes Hibernate generate SQL for the right database -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
<!-- 3. SQL Formatting -->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<!-- 4. Auto create/update schema (for development only) -->
<!-- update: Updates the schema if the model changes. -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 5. Mapping resource files -->
<!-- 告诉 Hibernate 去哪里找实体类的映射文件 -->
<mapping resource="com/example/entity/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
配置说明:
driver_class: MySQL 驱动类。url: 数据库连接 URL,请确保hibernate_db数据库已存在。username/password: 数据库用户名和密码。dialect: 指定数据库方言,让 Hibernate 生成针对特定数据库的优化 SQL。show_sql: 在控制台打印生成的 SQL 语句,便于调试。format_sql: 格式化输出的 SQL 语句,使其更易读。hbm2ddl.auto:none: 不自动创建或更新表。update: 当实体类发生变化时,自动更新数据库表结构(开发推荐)。create: 每次启动时都重新创建表,数据会丢失(测试用)。create-drop: 创建表,当 SessionFactory 关闭时,删除表。
<mapping>: 引入实体类的映射文件。
2 实体类映射配置 (*.hbm.xml)
我们采用 XML 方式进行映射,为每个实体类创建一个对应的 .hbm.xml 文件,文件名通常与实体类名相同,放在与实体类相同的包路径下。
3 整合配置:主配置文件引用映射文件
如上所示,在 hibernate.cfg.xml 中,我们通过 <mapping resource="..."/> 标签将 User.hbm.xml 引入。
第三部分:编写第一个 Hibernate 程序
我们将创建一个 User 实体,并将其保存到数据库中。
1 创建实体类 (User.java)
在 src/main/java/com/example/entity 目录下创建 User.java。
package com.example.entity;
public class User {
private Long id;
private String name;
private String email;
private int age;
// 无参构造器是必须的
public User() {
}
public User(String name, String email, int age) {
this.name = name;
this.email = email;
this.age = age;
}
// Getter 和 Setter 方法
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", age=" + age +
'}';
}
}
2 创建映射文件 (User.hbm.xml)
在 src/main/resources/com/example/entity 目录下创建 User.hbm.xml。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.example.entity">
<class name="User" table="t_user">
<!--
name: 实体类属性名
column: 数据库表列名
type: 数据类型 (可选,Hibernate 可推断)
-->
<id name="id" column="id">
<!--
generator: 主键生成策略
native: 自动选择数据库支持的最佳策略 (MySQL是自增, Oracle是序列)
-->
<generator class="native"/>
</id>
<property name="name" column="name"/>
<property name="email" column="email"/>
<property name="age" column="age"/>
</class>
</hibernate-mapping>
3 创建工具类 (HibernateUtil.java)
SessionFactory 的创建非常耗费资源,它是线程安全的,通常在整个应用中只创建一个,我们将其创建在静态代码块中,并提供一个 getSession() 方法来获取 Session。
在 src/main/java/com/example/util 目录下创建 HibernateUtil.java。
package com.example.util;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
// 1. 创建 Configuration 对象,加载 hibernate.cfg.xml 配置文件
Configuration configuration = new Configuration().configure();
// 2. 创建 ServiceRegistry 对象 (Hibernate 4 的核心变化)
// 这是 Hibernate 4 引入的,用于替代旧的 Properties 配置方式
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
.applySettings(configuration.getProperties())
.buildServiceRegistry();
// 3. 使用 Configuration 和 ServiceRegistry 创建 SessionFactory
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
4 编写测试代码 (App.java)
修改 src/main/java/com/example/App.java,编写保存用户的代码。
package com.example;
import com.example.entity.User;
import com.example.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
public class App {
public static void main(String[] args) {
// 1. 获取 SessionFactory
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
// 2. 打开一个 Session
Session session = sessionFactory.openSession();
// 3. 开启一个事务
Transaction transaction = null;
try {
transaction = session.beginTransaction();
// 4. 创建 User 对象
User user = new User("张三", "zhangsan@example.com", 25);
// 5. 保存对象 (此操作会生成 INSERT 语句,但尚未提交到数据库)
session.save(user);
// 6. 提交事务
transaction.commit();
System.out.println("用户保存成功!用户ID: " + user.getId());
} catch (Exception e) {
// 如果发生异常,回滚事务
if (transaction != null) {
transaction.rollback();
}
e.printStackTrace();
} finally {
// 7. 关闭 Session
session.close();
}
// 8. 关闭 SessionFactory (通常在应用关闭时执行)
sessionFactory.close();
}
}
运行程序:
- 确保您的 MySQL 服务正在运行,
hibernate_db数据库已创建。 - 运行
App.java。 - 查看控制台输出,您会看到 Hibernate 生成的建表和插入 SQL 语句。
- 连接到您的 MySQL 数据库,检查
t_user表,会发现新数据已成功插入。
第四部分:Hibernate 核心 API 详解
1 Configuration
负责加载 Hibernate 的配置信息(主要是 hibernate.cfg.xml),它会读取配置文件并创建一个 Configuration 实例。
2 ServiceRegistry
这是 Hibernate 4 的一个重大变化,在 Hibernate 3 中,配置信息直接传递给 SessionFactory,在 Hibernate 4 中,引入了 ServiceRegistry 作为中心服务注册表,所有 Hibernate 的服务(如连接池、缓存等)都注册在这里。Configuration 对象会根据配置文件创建并填充这个 ServiceRegistry。
3 SessionFactory
线程安全的重量级对象,它负责创建 Session 对象,并管理数据库连接池,一个数据库通常只需要一个 SessionFactory,它通常在应用启动时创建,在应用关闭时销毁。
4 Session
非线程轻量级对象,相当于 JDBC 中的 Connection,它用于执行持久化操作(增删改查)。Session 内部有一个缓存(一级缓存),它不是自动提交的,所有操作都必须在事务中完成,用完之后必须关闭。
5 Transaction
管理事务,在 Hibernate 中,所有写操作(save, update, delete, saveOrUpdate 等)都必须在事务中执行,否则不会提交到数据库。
6 Query 和 Criteria
Query: 用于执行 HQL(Hibernate Query Language)或原生 SQL,HQL 是一种面向对象的查询语言,类似于 SQL,但操作的是对象和属性而非表和列。Criteria: 一种面向对象的、类型安全的查询 API,通过 Java 代码动态构建查询条件,避免了书写字符串形式的 HQL。
第五部分:CRUD 操作
基于上面的 User 实体,我们演示完整的 CRUD。
1 创建 - save() / persist()
save(): 将一个临时态对象转变为持久态对象,并生成一个标识符(ID),它会在事务提交时执行 INSERT,返回生成的 ID。
persist(): 类似于 save(),但它保证不立即返回 ID,并且如果对象已经处于持久态,它不会执行任何操作,更符合 JPA 规范。
User newUser = new User("李四", "lisi@example.com", 30);
session.save(newUser); // 或 session.persist(newUser);
2 读取 - get() / load()
get(): 立即加载,它会立即执行 SELECT 语句,从数据库中查询数据,如果对象不存在,返回 null。
load(): 延迟加载,它返回一个代理对象,只有当您第一次访问该对象的非 ID 属性时,才会执行 SELECT 语句,如果对象不存在,会抛出 ObjectNotFoundException。
// 使用 get
User user1 = (User) session.get(User.class, 1L); // 立即查询
if (user1 != null) {
System.out.println("找到用户: " + user1.getName());
}
// 使用 load
User user2 = (User) session.load(User.class, 2L); // 此时不查询
System.out.println("用户ID: " + user2.getId()); // 访问 ID,不会触发查询,因为 ID 已由 Hibernate 管理
System.out.println("用户名: " + user2.getName()); // 访问非 ID 属性,此时才会触发 SELECT 查询
3 更新 - update()
当您修改一个已经处于持久态对象(从 get(), load(), query 获取的)的属性时,Hibernate 会在事务提交时自动同步这些更改到数据库,您不需要手动调用 update()。
但如果您修改的是一个游离态对象(即曾经是持久态,但 Session 已关闭或被清除),则需要手动调用 update() 将其重新关联到 Session。
// 场景1:持久态对象自动更新
User user = (User) session.get(User.class, 1L);
user.setName("王五更新"); // 修改属性
// transaction.commit(); // 提交时,Hibernate 会自动执行 UPDATE
// 场景2:游离态对象需要手动更新
User detachedUser = (User) session.get(User.class, 1L);
session.close(); // Session 关闭,user 变为游离态
detachedUser.setName("王五再次更新");
Session newSession = HibernateUtil.getSessionFactory().openSession();
Transaction newTx = newSession.beginTransaction();
newSession.update(detachedUser); // 将游离态对象重新附加到新的 Session
newTx.commit();
newSession.close();
4 删除 - delete()
可以从持久态或游离态对象中删除数据库记录。
// 场景1:从持久态对象删除 User userToDelete = (User) session.get(User.class, 1L); session.delete(userToDelete); // 标记为删除 // transaction.commit(); // 提交时执行 DELETE // 场景2:从游离态对象删除 User detachedUserToDelete = (User) session.get(User.class, 2L); session.close(); Session newSession = HibernateUtil.getSessionFactory().openSession(); Transaction newTx = newSession.beginTransaction(); newSession.delete(detachedUserToDelete); // 删除游离态对象 newTx.commit(); newSession.close();
5 HQL 查询示例
HQL 类似 SQL,但使用对象名和属性名。
// 1. 获取 Query 对象
String hql = "FROM User WHERE age > :minAge";
Query query = session.createQuery(hql);
// 2. 设置命名参数
query.setParameter("minAge", 25);
// 3. 执行查询,获取结果列表
List<User> users = query.list();
// 4. 遍历结果
for (User user : users) {
System.out.println(user);
}
第六部分:进阶主题
1 关系映射(一对多)
假设一个 Department 部门有多个 User 员工。
Department.java
package com.example.entity;
import java.util.HashSet;
import java.util.Set;
public class Department {
private Long id;
private String name;
private Set<User> users = new HashSet<>();
// getters, setters, constructors...
}
Department.hbm.xml
<hibernate-mapping package="com.example.entity">
<class name="Department" table="t_department">
<id name="id" column="id">
<generator class="native"/>
</id>
<property name="name" column="name"/>
<!-- 一对多关系 -->
<set name="users" table="t_user">
<key column="dept_id"/> <!-- t_user 表中的外键 -->
<one-to-many class="User"/>
</set>
</class>
</hibernate-mapping>
User.hbm.xml (多的一方,添加外键)
<hibernate-mapping package="com.example.entity">
<class name="User" table="t_user">
<id name="id" column="id">
<generator class="native"/>
</id>
<!-- ... 其他属性 ... -->
<property name="name" column="name"/>
<property name="email" column="email"/>
<property name="age" column="age"/>
<!-- 多对一关系 (可选,但推荐) -->
<many-to-one name="department" class="Department" column="dept_id"/>
</class>
</hibernate-mapping>
2 注解方式配置
Hibernate 4 同时支持 JPA 注解,可以省略 .hbm.xml 文件。
修改 hibernate.cfg.xml:
<!-- 移除 <mapping resource="..."/> --> <!-- 添加以下配置 --> <property name="hibernate.archive.autodetection">class</property>
修改 User.java (添加注解):
package com.example.entity;
import javax.persistence.*;
import java.io.Serializable;
@Entity // 声明为实体类
@Table(name = "t_user") // 指定对应的表名
public class User implements Serializable { // 实现 Serializable 是一个好习惯
@Id // 声明为主键
@GeneratedValue(strategy = GenerationType.IDENTITY) // 使用数据库自增策略
@Column(name = "id") // 指定列名
private Long id;
@Column(name = "name", nullable = false, length = 50)
private String name;
@Column(name = "email", unique = true)
private String email;
@Column(name = "age")
private int age;
// ... getters, setters, constructors ...
}
使用注解后,就不需要 User.hbm.xml 文件了,Hibernate 会自动扫描实体类。
这份教程涵盖了 Hibernate 4 的基础知识,包括环境搭建、核心配置、CRUD 操作和基本的关系映射,Hibernate 4 相比 Hibernate 3 最大的变化是引入了 ServiceRegistry,并全面拥抱了 JPA 标准。
通过学习本教程,您应该能够掌握 Hibernate 的基本使用,并为进一步学习更高级的特性(如缓存、集合映射、继承映射等)打下坚实的基础。
