JPA EntityManager功能与原理

JPA EntityManager功能与原理
最新回答
半袖桃花

2021-04-15 06:29:53

JPA,即Java Persistence API,是JavaEE中的一种orm标准,被视为一套接口。Hibernate等ORM引擎实现了这一标准。其中,EntityManager是一个接口,它提供了对象持久化的核心API。

常用的EntityManager实现有两个:Hibernate Session和单例注入的代理EntityManager。Hibernate Session真正实现了接口功能,而代理EntityManager会从当前事务上下文中找到正确的EntityManager,并代理其功能。实际上,我们直接使用的是代理EntityManager,间接使用了Hibernate Session。例如,open-session-in-view和“开启事务”都会在当前线程上下文中设置一个EntityManager,代理EntityManager在执行方法时会找到并调用它。如果当前线程上下文中不存在EntityManager,会报错。

EntityManager内部不一定开启了事务,并且它可能被复用。例如,open-session-in-view中创建的EntityManager就没有开始事务,该EntityManager可能在后续开启事务时被复用,并且在事务结束后也不会被销毁。在没有open-session-in-view的情况下,开启一个新事务就会在当前线程上下文中创建一个新的EntityManager,事务结束后会销毁自身创建的EntityManager。

EntityManager提供的API比Repository灵活,并可以完成所有持久化需求。以下介绍EntityManager中常用的API及其使用上的细节:

persist(Object entity)

必须在事务中调用,大概是一个Save的效果,将对象持久化。参数entity不能是Detached状态(游离态),一般用于新增。不会立即发出insert语句。

merge(Object entity)

必须在事务中调用,大概是一个SaveOrUpdate的效果,会根据参数entity的id立刻做一次select,如果查询到记录,则将entity的属性覆盖上去,不会立即发送update语句。如果没有查询到记录,会新增一个entity,不会立即发送insert语句。返回持久态的entity,该entity可能与传入的参数entity不同。

remove(Object entity)

必须在事务中调用,从数据库中删除,参数entity必须是持久化对象,不会立即发送delete语句。对被remove的entity做修改,无法保存到数据库中。尽量不要修改被remove过的entity。

find(Class entityClass, Object primaryKey)

根据id查找对象

flush()

在事务中调用,会把session中持久化对象的状态同步到数据库中,会在此时发送sql语句到数据库。事务结束前会自动flush。某些查询API在执行前也会自动flush,以保证查询到正确的结果。

public Query createQuery(String qlString)

public TypedQuery createQuery(String qlString, Class resultClass)

执行jpql语句,返回执行结果,执行前会自动调用flush。

public Query createNativeQuery(String sqlString)

public Query createNativeQuery(String sqlString, Class resultClass)

public Query createNativeQuery(String sqlString, String resultSetMapping)

执行原生sql,返回结果,执行前会自动调用flush。

entity的三种状态

瞬时态,直接new出来的,而且没有id。不存在于session中。

游离态,通常是new出来的,不存在于session中。但是有id,并且这个id在数据库中存在。

持久态,通常是orm引擎查询或save update后返回的对象。存在于session中,有id。

由于session(EntityManager)缓存的存在,在事务中,尽可能早地使用持久态对象,可以避免发生一些意外情况。