使用 Hibernate 和 JPA 进行 CRUD 操作





5.00/5 (1投票)
Hibernate ORM(简称 Hibernate)是 Java 编程语言的对象关系映射工具。它提供了一个框架,用于将面向对象的域模型映射到关系数据库。
引言
这是关于 Hibernate
和 JPA
的系列博文的第一部分。在本 教程中,我们将了解 Hibernate 和 JPA 的基础知识。
Hibernate 和 JPA 之间的关系是:Hibernate 是 JPA 规范的实现。
引用JPA 是一个规范。Hibernate 是其实现。
在这篇文章中,我们将创建一个简单的项目,执行 CRUD 操作,以演示 JPA 在 Hibernate 中的强大功能。
必备组件
项目结构
我们将创建一个 Maven 项目,并使用标准的目录结构,如下图所示。
. |__src/ | |__main/ | | |__java/ | | | |__com/ | | | | |__tutorial/ | | | | | |__Application.java | | | | | |__entity/ | | | | | | |__Person.java | | | | | |__repository/ | | | | | | |__PersonRepository.java | | | | | | |__PersonRepositoryImpl.java | | |__resources/ | | | |__META-INF/ | | | | |__persistence.xml | | | |__log4j2.properties |__pom.xml
设置依赖项
要开始使用 Hibernate 和 JPA,只需将以下内容添加到我们的 pom.xml
文件即可。
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.6.Final</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.193</version>
</dependency>
</dependencies>
完成此操作后,我们就可以开始编写代码了。
设置 JPA
我们将设置我们的 持久化单元
以进行 JPA 引导。persistence.xml
文件定义了一个持久化单元。persistence.xml 文件位于持久化单元根目录的 META-INF
目录下。它可用于指定持久化单元中包含的托管持久化类、这些类的对象/关系映射信息、用于模式生成和数据批量加载的脚本,以及持久化单元以及持久化单元的实体管理器和实体管理器工厂的其他配置信息。
对象/关系映射信息可以采用以下形式:持久化单元中包含的托管持久化类上的注解、持久化单元根目录的 META-INF
目录中包含的 orm.xml
文件、类路径上的一个或多个 XML 文件(从 persistence.xml
文件引用),或这些的组合。
对于我们简单的用例,我们将创建一个 persistence.xml
文件。
文件:src/main/resources/META-INF/persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="com.juliuskrah.tutorial" transaction-type="RESOURCE_LOCAL">
<class>com.tutorial.entity.Person</class>
<properties>
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create" />
<property name="javax.persistence.provider" value="org.hibernate.jpa.HibernatePersistenceProvider" />
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp:///~/test" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
</properties>
</persistence-unit>
</persistence>
从上面的代码片段中,我们已将持久化单元名称指定为 com.juliuskrah.tutorial
。这是我们将用于创建 EntityManagerFactory 的值。
在同一代码片段中,我们指定了要由 EntityManager 管理的 Entity 类(Person
)。
我们还指定了 Hibernate 将用于连接数据库的属性。这里最重要的属性是 javax.persistence.provider
,它告诉 JPA 使用哪个实现(在本例中为 Hibernate)。
接下来要做的就是创建映射到数据库表的 Entity 类。
文件:src/main/java/com/tutorial/entity/Person.java
<code class="language-java" data-lang="java"><span class="o"><font color="#000000">@Entity
public class Person implements Serializable {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String lastName;
// As of Hibernate 5.2 LocalDate is automatically mapped to sql type Date
private LocalDate dateOfBirth;
// As of Hibernate 5.2 LocalDateTime is automatically mapped to sql type Timestamp
private LocalDateTime createdDate;
private LocalDateTime modifiedDate;
// Getters and Setters omitted for brevity
}</font></span></code>
Person
类上的 @Entity
注解是映射元数据,它告诉 JPA将 Person 对象的字段映射到 PERSON 表中的列。例如,类型为 String
的 firstName
字段映射到类型为 varchar
的 FIRSTNAME
列。id
字段上的 @Id
注解将其标记为 PERSON
表的主键。@GeneratedValue
注解定义了生成主键值的策略(例如,自动增量)。
管理实体
设置好实体后,我们需要一种方法来管理其生命周期。实体由实体管理器管理,实体管理器由 javax.persistence.EntityManager
实例表示。每个 EntityManager
实例都关联一个持久化上下文:一个存在于特定数据存储中的托管实体实例集。持久化上下文定义了特定实体实例的创建、持久化和删除的范围。EntityManager
接口定义了用于与持久化上下文交互的方法。
EntityManager
API 会创建和删除持久化实体实例,按实体主键查找实体,并允许对实体执行查询。
JPA 规范定义了两种管理实体的方式:容器管理实体管理器
和应用程序管理实体管理器
。这超出了本教程的范围。为了简化起见,我们将使用应用程序管理的实体管理器。
我们将创建一个 PersonRepository 来方便我们的 CRUD 操作。
文件:src/main/java/com/tutorial/repository/PersonRepositoryImpl.java
<code class="language-java" data-lang="java"><span class="o"><font color="#000000">public class PersonRepositoryImpl implements PersonRepository {
private EntityManagerFactory emf = Persistence.createEntityManagerFactory("com.juliuskrah.tutorial");
private EntityManager em;
public PersonRepositoryImpl() {
em = emf.createEntityManager();
}
@Override
public Person create(Person person) {
em.getTransaction().begin();
em.persist(person);
em.getTransaction().commit();
return person;
}
@Override
public Person read(Long id) {
em.getTransaction().begin();
Person person = em.find(Person.class, id);
em.getTransaction().commit();
return person;
}
@Override
public Person update(Person person) {
em.getTransaction().begin();
person = em.merge(person);
em.getTransaction().commit();
return person;
}
@Override
public void delete(Person person) {
em.getTransaction().begin();
em.remove(person);
em.getTransaction().commit();
}
@Override
public void close() {
emf.close();
}
}</font></span></code>
存储库类顶部是
private EntityManagerFactory emf = Persistence.createEntityManagerFactory("com.juliuskrah.tutorial");
createEntityManagerFactory
方法接受 持久化单元名称
作为参数,您应该还记得该名称在我们的 persistence.xml
文件中设置为 com.juliuskrah.tutorial
。EntityManagerFactory 是一个工厂方法,用于创建 EntityManager 的实例。PersonRepository 包含执行 CRUD 操作的方法。
运行应用程序
我们将创建一个主类来测试我们的 CRUD 方法。
引用注意
在我们的persistence.xml
文件中,我们将属性javax.persistence.schema-generation.database.action
设置为drop-and-create
。这指示 Hibernate 在每次应用程序运行时删除并重新创建数据库。请不要在生产环境中使用此设置。在本系列的第三部分中,我们将讨论数据库迁移,这是推荐的方法。
文件:src/main/java/com/tutorial/Application.java
public class Application {
public static void main(String[] args) {
Server server = null;
PersonRepositoryImpl repository = null;
try {
// Start H2 embedded database
server = Server.createTcpServer().start();
Person person = new Person();
person.setFirstName("John");
person.setLastName("Doe");
person.setCreatedDate(LocalDateTime.now());
person.setDateOfBirth(LocalDate.of(1993, Month.APRIL, 12));
repository = new PersonRepositoryImpl();
// Create person
repository.create(person);
person = null;
// Hibernate creates a person proxy with an increment id of 1
person = repository.read(1L);
person.setModifiedDate(LocalDateTime.now());
person.setFirstName("Jane");
// Update person record
repository.update(person);
person = null;
// Read updated record
person = repository.read(1L);
// Delete person
repository.delete(person);
// This will return null
person = repository.read(1L);
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (repository != null)
repository.close();
if (server != null)
server.stop();
}
}
}
首先要做的就是启动 H2 嵌入式数据库服务器。
<span class="o"><font color="#000000">server = Server.createTcpServer().start();</font></span>
数据库服务器启动后,Hibernate 就可以在嵌入式数据库服务器上执行DDL和DML操作。通过调用 server.stop()
和 repository.close()
方法,我们在应用程序退出时进行资源清理。
结论
在这篇文章中,我们简要介绍了 JPA 及其 Hibernate 实现。我们了解了如何使用 JPA API 执行基本的 CRUD 操作。
一如既往,您可以在github 存储库中找到本指南的完整示例。期待下一篇文章,继续做酷炫的事情!。