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;
    }
}
相关推荐
愤怒的代码10 分钟前
Spring Boot对访问密钥加解密——HMAC-SHA256
java·spring boot·后端
栗豆包26 分钟前
w118共享汽车管理系统
java·spring boot·后端·spring·tomcat·maven
万亿少女的梦16839 分钟前
基于Spring Boot的网络购物商城的设计与实现
java·spring boot·后端
开心工作室_kaic2 小时前
springboot485基于springboot的宠物健康顾问系统(论文+源码)_kaic
spring boot·后端·宠物
0zxm2 小时前
08 Django - Django媒体文件&静态文件&文件上传
数据库·后端·python·django·sqlite
爱码少年6 小时前
springboot中责任链模式之简单应用
spring boot·责任链模式
苹果酱05677 小时前
「Mysql优化大师一」mysql服务性能剖析工具
java·vue.js·spring boot·mysql·课程设计
武昌库里写JAVA7 小时前
【MySQL】7.0 入门学习(七)——MySQL基本指令:帮助、清除输入、查询等
spring boot·spring·毕业设计·layui·课程设计
刘大辉在路上9 小时前
突发!!!GitLab停止为中国大陆、港澳地区提供服务,60天内需迁移账号否则将被删除
git·后端·gitlab·版本管理·源代码管理
追逐时光者11 小时前
免费、简单、直观的数据库设计工具和 SQL 生成器
后端·mysql