Hibernate 是 Java 领域最流行的 ORM(Object-Relational Mapping,对象关系映射)框架之一,它致力于解决 Java 对象与关系型数据库之间的映射问题,简化数据持久化操作,让开发者可以以面向对象的方式操作数据库,而无需过多关注底层 SQL 实现。
一、核心概念:ORM(对象关系映射)
ORM 是 Hibernate 的核心思想,它建立了 Java 对象与数据库表之间的映射关系:
- Java 对象(实体类) ↔ 数据库表
- 对象的属性 ↔ 表的列
- 对象的实例 ↔ 表的行(记录)
通过 ORM,开发者可以直接操作 Java 对象(如创建、修改、删除),Hibernate 会自动将这些操作转换为对应的 SQL 语句,避免了手动编写大量 JDBC 样板代码。
二、Hibernate 核心组件
Hibernate 的核心功能由以下组件协同实现:
-
Configuration(配置对象)
负责加载 Hibernate 配置文件(如
hibernate.cfg.xml
)和映射文件,解析配置信息(如数据库连接参数、方言等),并生成SessionFactory
。 -
SessionFactory(会话工厂)
- 由
Configuration
创建,是线程安全的重量级对象(通常整个应用只需要一个实例)。 - 负责创建
Session
对象,同时维护 Hibernate 的二级缓存。
- 由
-
Session(会话)
- 是非线程安全的轻量级对象,代表与数据库的一次连接(会话)。
- 是 Hibernate 操作数据库的核心接口,提供 CRUD(增删改查)操作方法(如
save()
、get()
、update()
、delete()
)。 - 维护 Hibernate 的一级缓存(默认开启)。
-
Transaction(事务)
- 管理数据库事务,通过
Session.beginTransaction()
获取。 - 支持事务的提交(
commit()
)和回滚(rollback()
),确保数据操作的原子性。
- 管理数据库事务,通过
-
Query(查询对象)
- 用于执行 HQL(Hibernate Query Language)查询或原生 SQL 查询。
- 通过
Session.createQuery()
创建,支持参数绑定、分页等功能。
-
Criteria(条件查询)
- 一种面向对象的查询 API,通过链式调用构建查询条件,无需编写 HQL 语句。
三、核心配置
Hibernate 的运行依赖两类配置文件:
1. 主配置文件(hibernate.cfg.xml
)
用于配置数据库连接、Hibernate 全局属性等,通常放在src/main/resources
目录下。示例:
<?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>
<!-- 数据库连接参数 -->
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</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>
<!-- 其他配置 -->
<property name="hibernate.show_sql">true</property> <!-- 打印生成的SQL -->
<property name="hibernate.format_sql">true</property> <!-- 格式化SQL -->
<property name="hibernate.hbm2ddl.auto">update</property> <!-- 自动生成表结构(create/update/create-drop/validate) -->
<!-- 映射文件路径 -->
<mapping resource="com/example/entity/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
2. 映射文件(如User.hbm.xml
)或注解
用于定义 Java 实体类与数据库表的映射关系,有两种方式:
-
XML 映射 (传统方式):
示例
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"> <!-- 主键映射 --> <id name="id" column="user_id"> <!-- 主键生成策略:自增 --> <generator class="identity"/> </id> <!-- 属性与列映射 --> <property name="username" column="username" length="50" not-null="true"/> <property name="age" column="age"/> <property name="createTime" column="create_time" type="java.util.Date"/> </class> </hibernate-mapping>
-
注解映射 (主流方式,简化配置):
示例
User.java
:import javax.persistence.*; import java.util.Date; @Entity @Table(name = "t_user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增主键 @Column(name = "user_id") private Integer id; @Column(name = "username", length = 50, nullable = false) private String username; @Column(name = "age") private Integer age; @Column(name = "create_time") private Date createTime; // getter/setter }
四、主键生成策略
Hibernate 提供了多种主键生成策略(通过@GeneratedValue
或<generator>
配置),适用于不同场景:
策略 | 说明 | 适用场景 |
---|---|---|
IDENTITY |
依赖数据库自增列(如 MySQL 的 AUTO_INCREMENT) | MySQL、SQL Server 等 |
SEQUENCE |
依赖数据库序列(如 Oracle 的 SEQUENCE) | Oracle、PostgreSQL 等 |
AUTO |
Hibernate 自动选择适合数据库的策略 | 跨数据库开发 |
TABLE |
用一张专门的表维护主键生成,兼容性强但性能较差 | 所有数据库(不推荐) |
UUID |
生成全局唯一的 UUID 字符串作为主键 | 分布式系统(避免主键冲突) |
五、关联关系映射
在面向对象中,实体间存在关联关系(如一对一、一对多、多对多),Hibernate 通过映射配置实现这些关系与数据库外键的关联。
1. 一对多(如 "部门 - 员工")
-
部门(一)包含多个员工(多),员工属于一个部门。
-
注解示例:
// 部门类(一的一方) @Entity @Table(name = "t_department") public class Department { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; // 一对多关联:部门包含多个员工 @OneToMany(mappedBy = "department", cascade = CascadeType.ALL) private List<Employee> employees = new ArrayList<>(); // getter/setter } // 员工类(多的一方) @Entity @Table(name = "t_employee") public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; // 多对一关联:员工属于一个部门(外键在员工表) @ManyToOne @JoinColumn(name = "dept_id") // 外键列名 private Department department; // getter/setter }
2. 多对多(如 "学生 - 课程")
-
一个学生可以选多门课程,一门课程可以被多个学生选,通常通过中间表关联。
-
注解示例:
// 学生类 @Entity @Table(name = "t_student") public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; // 多对多关联:学生选多门课程 @ManyToMany @JoinTable( name = "t_student_course", // 中间表名 joinColumns = @JoinColumn(name = "student_id"), // 学生表外键 inverseJoinColumns = @JoinColumn(name = "course_id") // 课程表外键 ) private Set<Course> courses = new HashSet<>(); // getter/setter } // 课程类 @Entity @Table(name = "t_course") public class Course { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; // 多对多关联:课程被多个学生选(mappedBy指向学生类中的courses属性) @ManyToMany(mappedBy = "courses") private Set<Student> students = new HashSet<>(); // getter/setter }
六、HQL 查询
HQL(Hibernate Query Language)是面向对象的查询语言,语法类似 SQL,但操作的是实体类和属性,而非表和列。
示例:
// 获取Session
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// 1. 查询所有用户
Query<User> query1 = session.createQuery("FROM User", User.class);
List<User> users = query1.list();
// 2. 条件查询(年龄>18的用户)
Query<User> query2 = session.createQuery("FROM User WHERE age > :age", User.class);
query2.setParameter("age", 18); // 参数绑定
List<User> adults = query2.list();
// 3. 分页查询(第1页,每页10条)
Query<User> query3 = session.createQuery("FROM User ORDER BY id DESC", User.class);
query3.setFirstResult(0); // 起始索引
query3.setMaxResults(10); // 每页条数
List<User> page1 = query3.list();
tx.commit();
session.close();
七、缓存机制
Hibernate 提供两级缓存提升性能:
-
一级缓存(Session 级缓存)
- 绑定到
Session
,生命周期与Session
一致。 - 默认开启,同一个
Session
中多次查询同一对象,只会执行一次 SQL(后续从缓存获取)。
- 绑定到
-
二级缓存(SessionFactory 级缓存)
- 全局缓存,被所有
Session
共享,生命周期与SessionFactory
一致。 - 需要手动配置(如使用 Ehcache),适用于查询频繁、修改少的数据(如字典表)。
- 全局缓存,被所有
八、Hibernate 工作流程
- 加载
hibernate.cfg.xml
配置文件,创建Configuration
对象。 - 通过
Configuration
创建SessionFactory
(读取映射关系)。 - 从
SessionFactory
获取Session
,开启事务(Transaction
)。 - 通过
Session
执行 CRUD 操作(Hibernate 自动转换为 SQL)。 - 提交事务(或回滚异常)。
- 关闭
Session
和SessionFactory
。
九、Hibernate 的优势与局限
- 优势 :
简化持久化代码、面向对象编程、数据库无关性(通过方言)、缓存支持、事务管理等。 - 局限 :
简单查询时性能略低于原生 JDBC、配置复杂(早期)、对 SQL 优化灵活性较低。
总结:Hibernate 通过 ORM 思想极大简化了 Java 与数据库的交互,是企业级开发中处理数据持久化的重要工具,尤其适合复杂对象关系的场景。