Hibernate 5 引导API
1. 概述
在本教程中,我们将探索用于初始化和启动 Hibernate SessionFactory 的新机制。 我们将特别关注新的原生引导过程,因为它在 5.0 版中进行了重新设计。
在 5.0 版之前,应用程序必须使用 Configuration 类来引导 SessionFactory。这种方法现在已被弃用,因为 Hibernate 文档建议使用基于 ServiceRegistry 的新 API。
简而言之,构建 SessionFactory就是拥有一个ServiceRegistry 实现,该实现包含 Hibernate 在启动和运行期间所需的Service。
2. Maven依赖
在我们开始探索新的引导过程之前,我们需要将hibernate-core jar 文件添加到项目类路径中。在一个基于 Maven 的项目中,我们只需要在pom.xml文件中声明这个依赖:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.0.Final</version>
</dependency>
由于 Hibernate 是一个 JPA 提供者,这也将包括 JPA API 依赖传递。
我们还需要我们正在使用的数据库的 JDBC 驱动程序。在此示例中,我们将使用嵌入式 H2 数据库:
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.197</version>
</dependency>
随意 在 Maven Central 上查看最新版本的*hibernate-core *和H2 驱动程序。
3. 引导 API
引导是指构建和初始化SessionFactory 的过程。
为了达到这个目的,我们需要一个ServiceRegistry 来保存Hibernate 所需的Service。从这个注册表中,我们可以构建一个Metadata 对象,该对象表示应用程序的域模型及其到数据库的映射。
让我们更详细地探索这些主要对象。
3.1. Service
在深入研究ServiceRegistry概念之前,我们首先需要了解什么是Service。在 Hibernate 5.0 中,Service是一种由同名接口表示的功能类型:
org.hibernate.service.Service
默认情况下,Hibernate 为最常见的 Services提供了实现,在大多数情况下它们就足够了。否则,我们可以构建自己的 Service来修改原始 Hibernate 功能或添加新功能。
在下一小节中,我们将展示 Hibernate 如何通过名为ServiceRegistry的轻量级容器使这些Service可用。
3.2. ServiceRegistry
构建SessionFactory的第一步是创建一个ServiceRegistry。这允许持有各种 Service,这些服务提供 Hibernate 所需的功能并且基于Java SPI 功能。
从技术上讲,我们可以将ServiceRegistry 视为一个轻量级的依赖注入工具,其中 bean 的类型仅为Service。
ServiceRegistry有两种类型, 它们是分层的。 第一个是BootstrapServiceRegistry,它没有父级并拥有这三个必需的服务:
- ClassLoaderService: 允许Hibernate与各种运行时环境的ClassLoader 进行交互
- IntegratorService: 控制Integrator服务的发现和管理,允许第三方应用程序与 Hibernate 集成
- StrategySelector: 解析各种策略合约的实现
**为了构建BootstrapServiceRegistry实现,我们使用 BootstrapServiceRegistryBuilder工厂类,**它允许以类型安全的方式自定义这三个服务:
BootstrapServiceRegistry bootstrapServiceRegistry = new BootstrapServiceRegistryBuilder()
.applyClassLoader()
.applyIntegrator()
.applyStrategySelector()
.build();
**第二个ServiceRegistry是StandardServiceRegistry,它建立在前面的BootstrapServiceRegistry之上,拥有上面提到的三个 Service。此外,它还包含 Hibernate 所需的各种其他Service,列在 StandardServiceInitiators 类中。
和之前的注册中心一样,我们使用 StandardServiceRegistryBuilder来创建 StandardServiceRegistry 的一个实例:
StandardServiceRegistryBuilder standardServiceRegistry =
new StandardServiceRegistryBuilder();
在底层,StandardServiceRegistryBuilder创建并使用了一个 BootstrapServiceRegistry 实例。我们还可以使用重载的构造函数来传递已经创建的实例:
BootstrapServiceRegistry bootstrapServiceRegistry =
new BootstrapServiceRegistryBuilder().build();
StandardServiceRegistryBuilder standardServiceRegistryBuilder =
new StandardServiceRegistryBuilder(bootstrapServiceRegistry);
我们使用此构建器从资源文件加载配置,例如默认的 hibernate.cfg.xml,最后,我们调用*build()*方法来获取 StandardServiceRegistry 的实例。
StandardServiceRegistry standardServiceRegistry = standardServiceRegistryBuilder
.configure()
.build();
3.3. Metadata
通过实例化BootstrapServiceRegistry 或 StandardServiceRegistry类型 的ServiceRegistry配置了所需的所有Service后,我们现在需要提供应用程序的域模型及其数据库映射的表示。
MetadataSources类负责:
MetadataSources metadataSources = new MetadataSources(standardServiceRegistry);
metadataSources.addAnnotatedClass();
metadataSources.addResource()
接下来,我们得到一个Metadata实例,我们将在最后一步中使用它:
Metadata metadata = metadataSources.buildMetadata();
3.4. SessionFactory
最后一步是从之前创建的元数据创建SessionFactory:
SessionFactory sessionFactory = metadata.buildSessionFactory();
我们现在可以打开一个Session 并开始持久化和读取实体:
Session session = sessionFactory.openSession();
Movie movie = new Movie(100L);
session.persist(movie);
session.createQuery("FROM Movie").list();