什么是EntityManager
在JPA规范里,EntityManager扮演着执行持久化操作的关键角色。
只有当普通Java对象被EntityManager持久化后,它们才能转变为持久化对象。
EntityManager 负责管理O/R映射,即实体类与底层数据源之间的关系。它不仅可以管理和更新Entity Bean,还可以基于主键查询Entity Bean,甚至通过JPQL语句进行实体查询。
java
**
* Interface used to interact with the persistence context.
*//这里讲述了EntityManager的作用!!!
* <p> An <code>EntityManager</code> instance is associated with
* a persistence context. A persistence context is a set of entity
* instances in which for any persistent entity identity there is
* a unique entity instance. Within the persistence context, the
* entity instances and their lifecycle are managed.
* The <code>EntityManager</code> API is used
* to create and remove persistent entity instances, to find entities
* by their primary key, and to query over entities.
*
* <p> The set of entities that can be managed by a given
* <code>EntityManager</code> instance is defined by a persistence
* unit. A persistence unit defines the set of all classes that are
* related or grouped by the application, and which must be
* colocated in their mapping to a single database.
*
* @see Query
* @see TypedQuery
* @see CriteriaQuery
* @see PersistenceContext
*
* @since Java Persistence 1.0
*/
public interface EntityManager {
//...
}
Java Persistence API (JPA) 中的 EntityManager
是一个接口,它主要负责数据库操作的核心功能。以下是其主要作用:
-
创建和删除数据库记录 :
EntityManager
提供了persist()
和remove()
方法来插入和删除数据库记录。 -
查询数据库记录 :
EntityManager
提供了find()
和createQuery()
等方法来查询数据库记录。 -
更新数据库记录 :
EntityManager
提供了merge()
方法来更新数据库记录。 -
管理实体的生命周期 :
EntityManager
能够跟踪实体对象的状态,并在适当的时候进行持久化操作。 -
事务管理 :
EntityManager
提供了getTransaction()
方法来获取当前事务,然后可以对事务进行提交或回滚。
总的来说,EntityManager
是 JPA 中的核心接口,它提供了一种抽象的方式来管理数据库操作,使得开发者可以更加专注于业务逻辑的开发,而不需要关心底层的 SQL 语句。
数据状态管理
-
新建状态: 新创建的对象,尚未拥有持久性主键;
-
持久化状态:已经拥有持久性主键并和持久化建立了上下文环境;
-
游离状态:拥有持久化主键,但是没有与持久化建立上下文环境;
-
删除状态: 拥有持久化主键,已经和持久化建立上下文环境,但是从数据库中删除。
数据操作
EntityInformation
是 Spring Data JPA 中的一个接口,它提供了关于实体类的元数据。这些信息包括实体类的 ID 类型、实体类类型等。以下是 EntityInformation
的主要作用:
-
获取实体类的 ID :
EntityInformation
提供了getId(entity)
方法来获取实体对象的 ID。 -
获取实体类的 ID 类型 :
EntityInformation
提供了getIdType()
方法来获取实体类 ID 的 Java 类型。 -
获取实体类的类型 :
EntityInformation
提供了getJavaType()
方法来获取实体类的 Java 类型。 -
检查实体是否为新的 :
EntityInformation
提供了isNew(entity)
方法来检查实体是否为新的(即还未持久化到数据库中)。
总的来说,EntityInformation
提供了一种抽象的方式来获取和操作实体类的元数据,这对于编写通用的、可重用的数据访问代码非常有用。
具体实现
java
package cn.soboys.springbootjpa.jpa;
import cn.soboys.springbootjpa.jpa.conditions.Wrapper;
import cn.soboys.springbootjpa.jpa.config.JpaDaoHelper;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.util.Assert;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.transaction.Transactional;
import java.io.Serializable;
/**
* @author 公众号 程序员三时
* @version 1.0
* @date 2023/7/24 18:31
* @webSite https://github.com/coder-amiao
*/
public class CustomBaseRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements BaseRepository<T, ID> {
/**
* 实体类
*/
private final Class<T> entityClass;
/**
* 实体类名
*/
private final String entityName;
/**
* 实体管理器
*/
private final EntityManager entityManager;
private final JpaEntityInformation<T, ?> entityInformation;
@SuppressWarnings("all")
public CustomBaseRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
Assert.notNull(entityInformation, "JpaEntityInformation must not be null!");
Assert.notNull(entityManager, "EntityManager must not be null!");
this.entityInformation = entityInformation;
this.entityManager = entityManager;
this.entityName = entityInformation.getEntityName();
this.entityClass = entityInformation.getJavaType();
JpaDaoHelper.setEntityManager(entityManager);
}
@Override
@Transactional
public T updateById(T entity) {
entityInformation.getRequiredId(entity);
return entityManager.merge(entity);
}
@Override
@Transactional
public T saveOrUpdate(T entity) {
if (entityInformation.isNew(entity)) {
entityManager.persist(entity); //保存
return entity;
} else {
return entityManager.merge(entity); //更新
}
}
@Override
@Transactional
public T update(Wrapper<T> updateWrapper) {
//this.entityManager.createQuery()
return null;
}
}