JPA数据库操作EntityManager状态管理

什么是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 是一个接口,它主要负责数据库操作的核心功能。以下是其主要作用:

  1. 创建和删除数据库记录EntityManager 提供了 persist()remove() 方法来插入和删除数据库记录。

  2. 查询数据库记录EntityManager 提供了 find()createQuery() 等方法来查询数据库记录。

  3. 更新数据库记录EntityManager 提供了 merge() 方法来更新数据库记录。

  4. 管理实体的生命周期EntityManager 能够跟踪实体对象的状态,并在适当的时候进行持久化操作。

  5. 事务管理EntityManager 提供了 getTransaction() 方法来获取当前事务,然后可以对事务进行提交或回滚。

总的来说,EntityManager 是 JPA 中的核心接口,它提供了一种抽象的方式来管理数据库操作,使得开发者可以更加专注于业务逻辑的开发,而不需要关心底层的 SQL 语句。

数据状态管理

  1. 新建状态: 新创建的对象,尚未拥有持久性主键;

  2. 持久化状态:已经拥有持久性主键并和持久化建立了上下文环境;

  3. 游离状态:拥有持久化主键,但是没有与持久化建立上下文环境;

  4. 删除状态: 拥有持久化主键,已经和持久化建立上下文环境,但是从数据库中删除。

数据操作

EntityInformation 是 Spring Data JPA 中的一个接口,它提供了关于实体类的元数据。这些信息包括实体类的 ID 类型、实体类类型等。以下是 EntityInformation 的主要作用:

  1. 获取实体类的 IDEntityInformation 提供了 getId(entity) 方法来获取实体对象的 ID。

  2. 获取实体类的 ID 类型EntityInformation 提供了 getIdType() 方法来获取实体类 ID 的 Java 类型。

  3. 获取实体类的类型EntityInformation 提供了 getJavaType() 方法来获取实体类的 Java 类型。

  4. 检查实体是否为新的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;
    }
}
相关推荐
Minyy111 小时前
SpringBoot程序的创建以及特点,配置文件,LogBack记录日志,配置过滤器、拦截器、全局异常
xml·java·spring boot·后端·spring·mybatis·logback
武昌库里写JAVA2 小时前
39.剖析无处不在的数据结构
java·vue.js·spring boot·课程设计·宠物管理
画个大饼3 小时前
Go语言实战:快速搭建完整的用户认证系统
开发语言·后端·golang
艺杯羹5 小时前
JDBC之ORM思想及SQL注入
数据库·sql·jdbc·orm·sql注入
萌萌哒草头将军7 小时前
🚀🚀🚀 Prisma 爱之初体验:一款非常棒的 ORM 工具库
前端·javascript·orm
李白的粉8 小时前
基于springboot的在线教育系统
java·spring boot·毕业设计·课程设计·在线教育系统·源代码
小马爱打代码8 小时前
SpringBoot原生实现分布式MapReduce计算
spring boot·分布式·mapreduce
iuyou️8 小时前
Spring Boot知识点详解
java·spring boot·后端
一弓虽9 小时前
SpringBoot 学习
java·spring boot·后端·学习
姑苏洛言9 小时前
扫码小程序实现仓库进销存管理中遇到的问题 setStorageSync 存储大小限制错误解决方案
前端·后端