Contents

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();

**第二个ServiceRegistryStandardServiceRegistry,它建立在前面的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();