1. 简介
在这篇文章中,我们将讨论 Hibernate 以及 Java Persistence API(JPA),并重点分析它们之间的区别。
我们会先从 JPA 是什么、怎么用以及它的核心概念开始入手。
然后,再看看 Hibernate 和 EclipseLink 在整个体系中扮演的角色。
2. 对象关系映射(ORM)
在深入 JPA 之前,我们有必要先理解 对象关系映射(Object-Relational Mapping,简称 ORM) 的概念。
简单来说,ORM 就是将 Java 对象直接持久化到数据库表的过程。通常,被持久化的对象名会成为表名,对象中的每个字段则对应表中的列。表结构确定后,每一行数据就对应应用中的一个记录。
3. JPA 概述
Java Persistence API(JPA)是一个规范,它定义了如何在 Java 应用中管理关系型数据。JPA 规范定义了一组概念,说明哪些对象需要被持久化,以及如何进行持久化。
⚠️注意:JPA 本身只是一个规范,它需要具体的实现才能工作——这一点我们稍后再详细讲。
接下来,我们来看看 JPA 实现必须涵盖的一些核心概念。
3.1. 实体(Entity)
javax.persistence.Entity
注解用于标记哪些对象需要被持久化到数据库。对于每个被标记的实体,JPA 会在数据库中创建一张对应的表。
此外,每个实体类都需要定义一个主键,使用 @Id
注解标记。配合 @GeneratedValue
注解,我们可以指定主键在数据插入时自动递增。
来看一个简单的实体示例:
@Entity
public class Car {
@GeneratedValue
@Id
public long id;
// getters and setters
}
不过,目前这段代码还不会对程序有任何影响——因为 JPA 本身并不提供任何实现代码。
3.2. 字段持久化
JPA 的另一个核心概念是字段持久化。当一个 Java 对象被定义为实体后,其所有字段默认都会被持久化为表中的列。
如果某个字段我们不希望被持久化,可以用 @Transient
注解将其标记为瞬态字段。
3.3. 关系映射
JPA 还规定了如何在应用中管理不同数据库表之间的关系。我们可以通过以下四个注解来描述:
@OneToOne
@OneToMany
@ManyToOne
@ManyToMany
举个例子:
@Entity
public class SteeringWheel {
@OneToOne
private Car car;
// getters and setters
}
上面的代码表示 SteeringWheel
类与 Car
类之间是一对一的关系。
3.4. 实体管理器(EntityManager)
最后,javax.persistence.EntityManager
类定义了与数据库交互的操作。EntityManager 提供了常见的 CRUD 操作(增删改查),这些操作会被持久化到数据库中。
4. JPA 实现选择
JPA 只是一个规范,我们需要选择一个具体的实现来提供实际功能。否则,我们就得自己实现所有相关类,那可就太费劲了。
目前市面上有不少 JPA 实现可以选择,各有优劣。在选择时,建议从以下几个维度考虑:
- 项目成熟度 —— 这个实现存在多久了?文档是否完善?
- 生态支持 —— 有没有有用的子项目或工具?
- 社区支持 —— 出问题时有没有人能帮你解决?
- 性能表现 —— 这个实现的执行效率如何?
下面我们就来看看几种主流的 JPA 实现。
5. Hibernate
Hibernate 是一个成熟的 ORM 框架,同时也是 JPA 的一种实现。它是最流行的 JPA 实现之一,拥有庞大的社区支持。
Hibernate 实现了所有 javax.persistence
中定义的类,同时还提供了一些超出 JPA 规范的功能,例如:
虽然这些扩展功能很实用,但如果应用只需要基础的 JPA 功能,其实并不需要它们。
来看一个例子,Hibernate 在 @Entity
基础上提供了额外的元数据支持,比如:
✅ @Table
:指定实体对应的表名
✅ @BatchSize
:设置批量加载实体的数量
此外,Hibernate 还提供了一些 JPA 没有规定的功能,适合在大型项目中使用:
- 使用
@SQLInsert
、@SQLUpdate
、@SQLDelete
自定义 CRUD SQL 语句 - 支持软删除(soft delete)
- 使用
@Immutable
注解定义不可变实体
如需深入了解 Hibernate,可以参考我们的 Spring 持久层教程系列。
6. EclipseLink
EclipseLink 是由 Eclipse 基金会开发的开源 JPA 实现。除了 JPA,它还支持其他持久化标准,例如 Java Architecture for XML Binding(JAXB)。
简单来说,JAXB 可以将对象映射为 XML 格式,而非数据库表。
再来看 @Entity
的实现,EclipseLink 提供了不同的扩展。虽然没有像 Hibernate 那样的 @BatchSize
,但它也提供了 Hibernate 所不具备的功能,例如:
✅ @ReadOnly
:标记实体为只读
✅ @Struct
:将类映射为数据库中的 struct 类型
如需了解更多 EclipseLink 的特性,可以参考我们的 EclipseLink 与 Spring 整合指南。
7. 总结
这篇文章我们主要介绍了 Java Persistence API(JPA)的基本概念,并对比了 Hibernate 和 EclipseLink 这两种主流的 JPA 实现。
简单总结一下:
- ✅ JPA 是一个规范,不是具体实现
- ✅ Hibernate 是最成熟、生态最丰富的 JPA 实现之一
- ✅ EclipseLink 是 Eclipse 基金会推出的开源 JPA 实现,支持多种持久化标准
选择哪种实现,最终还是要看项目需求、团队熟悉度和性能要求。