深入理解JPA的flush()方法及其使用场景
在Java Persistence API(JPA)中,EntityManager
是我们与数据库交互的核心接口。其中一个关键的方法就是 flush()
,它负责将持久化上下文(persistence context)中的更改同步到数据库中。本文将详细探讨 flush()
方法的工作原理、使用场景以及如何通过设置不同的刷新模式来优化性能。
flush() 方法的工作原理
当我们调用 EntityManager#flush()
方法时,它会执行所有延迟的DML语句(如insert、update、delete等),但不会提交当前事务。这意味着,尽管数据库已经接收到了更改,但这些更改对其他 EntityManager
实例或外部数据库客户端而言是不可见的,直到事务提交。
使用flush()的场景
我们可能需要使用 flush()
来释放当前 EntityManager
持久化上下文中积累的大量运行时内存缓存,或者为了在同一个事务中的下一个实体管理器操作,例如,当数据库查询需要检索在 EntityManager
持久化上下文中不可用的信息时。
设置刷新模式
我们可以使用 EntityManager#setFlushMode(FlushModeType)
来设置刷新行为,包括以下两种模式:
- FlushModeType.AUTO:自动刷新可以在事务提交前被调用,具体时机由
TransactionManager
控制,通常在查询执行前发生。这是默认模式。 - FlushModeType.COMMIT:仅在事务提交或手动调用
TransactionManager#flush()
时刷新。
实例演示
以下是一个使用 flush()
方法的示例。在这个示例中,我们将刷新模式设置为 FlushModeType.COMMIT
,这意味着我们想要手动控制刷新操作。
@Entity
public class Employee {
@Id
private Integer id;
private String name;
private String department;
// 构造函数和getter/setter省略
}
public class ExampleMain {
private static void persistEntity(EntityManagerFactory emf) {
EntityManager em = emf.createEntityManager();
em.setFlushMode(FlushModeType.COMMIT);
List<Employee> employeeList = getNewEmployees();
em.getTransaction().begin();
for (Employee employee : employeeList) {
em.persist(employee);
}
em.flush(); // 手动刷新
showPersistedITEmployees(em);
em.getTransaction().commit();
em.close();
}
private static void showPersistedITEmployees(EntityManager em) {
Query query = em.createQuery("Select e from Employee e where e.department ='IT'");
System.out.println("-- IT employees persisted list --");
List<Employee> list = (List<Employee>) query.getResultList();
list.forEach(System.out::println);
}
}
如果我们注释掉 flush()
调用,将不会打印出任何IT部门的员工信息,这展示了 flush()
的作用,即让更改对同一个 EntityManager
实例的后续操作可见。
示例项目
本示例项目使用了以下依赖和技术:
- h2 1.4.196: H2数据库引擎
- hibernate-core 5.2.10.Final: Hibernate提供的O/RM核心功能
- JDK 1.8
- Maven 3.3.9
通过本文的探讨,我们了解到 flush()
方法在JPA中的重要性以及如何根据不同的业务需求来设置刷新模式。希望这能帮助你在实际开发中更有效地使用JPA。