EntityManager、EntityManagerFactory

本文深入解析了Java Persistence API (JPA) 中的核心组件EntityManager及其使用方式。探讨了EntityManager的两种托管方式:容器托管和应用托管,并介绍了EntityManagerFactory的作用及其实例创建过程。

1、EntityManager

An instance of the interface javax. persistence. Entity Manager is used to persist, retrieve, update and remove entities to/from the database. Depending on the environment, an EntityManager can be used in following two ways:

  • 容器托管 - Container-managed entity manger: In this case, the instance of EntityManager is managed automatically by the container. We typically obtain the instance of EntityManager by injecting it with @PersistenceContext. This is only applicable to Java EE environment
  • 应用托管 - Application-managed entity manager: In this case, we have to explicitly obtain and manage the instance(s) of EntityManager. This is applicable to both Java EE or stand-alone/Java SE applications.

EntityManager是JPA中用于增删改查的接口,它的作用相当于一座桥梁,连接内存中的java对象和数据库的数据存储。 

EntityManager托管方式由两种:容器托管(EntityManger && PersistenceContext)和 应用托管(EntityManagerFactory && PersistenceUnit),比较简单的方式是采用容器托管。

关于PersistenceUnit与PersistenceContext,请移步另一文章:https://blog.youkuaiyun.com/tfstone/article/details/119330721

1、容器托管(持久化上下文获取)

@PersistenceContext
private EntityManager em;

2、应用托管(从持久化单元获取)

#从EntityManagerFactory获取(EntityManagerFactory从容器获取)
@PersistenceUnit
private EntityManagerFactory emf;
EntityManager em = emf.createEntityManager();

Plus:SpingBoot启动时,默认PersistenceUnit

源码: 

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package javax.persistence;

import java.util.List;
import java.util.Map;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaDelete;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.CriteriaUpdate;
import javax.persistence.metamodel.Metamodel;

public interface EntityManager {
    void persist(Object var1);

    <T> T merge(T var1);

    void remove(Object var1);

    <T> T find(Class<T> var1, Object var2);

    <T> T find(Class<T> var1, Object var2, Map<String, Object> var3);

    <T> T find(Class<T> var1, Object var2, LockModeType var3);

    <T> T find(Class<T> var1, Object var2, LockModeType var3, Map<String, Object> var4);

    <T> T getReference(Class<T> var1, Object var2);

    void flush();

    void setFlushMode(FlushModeType var1);

    FlushModeType getFlushMode();

    void lock(Object var1, LockModeType var2);

    void lock(Object var1, LockModeType var2, Map<String, Object> var3);

    void refresh(Object var1);

    void refresh(Object var1, Map<String, Object> var2);

    void refresh(Object var1, LockModeType var2);

    void refresh(Object var1, LockModeType var2, Map<String, Object> var3);

    void clear();

    void detach(Object var1);

    boolean contains(Object var1);

    LockModeType getLockMode(Object var1);

    void setProperty(String var1, Object var2);

    Map<String, Object> getProperties();

    Query createQuery(String var1);

    <T> TypedQuery<T> createQuery(CriteriaQuery<T> var1);

    Query createQuery(CriteriaUpdate var1);

    Query createQuery(CriteriaDelete var1);

    <T> TypedQuery<T> createQuery(String var1, Class<T> var2);

    Query createNamedQuery(String var1);

    <T> TypedQuery<T> createNamedQuery(String var1, Class<T> var2);

    Query createNativeQuery(String var1);

    Query createNativeQuery(String var1, Class var2);

    Query createNativeQuery(String var1, String var2);

    StoredProcedureQuery createNamedStoredProcedureQuery(String var1);

    StoredProcedureQuery createStoredProcedureQuery(String var1);

    StoredProcedureQuery createStoredProcedureQuery(String var1, Class... var2);

    StoredProcedureQuery createStoredProcedureQuery(String var1, String... var2);

    void joinTransaction();

    boolean isJoinedToTransaction();

    <T> T unwrap(Class<T> var1);

    Object getDelegate();

    void close();

    boolean isOpen();

    EntityTransaction getTransaction();

    EntityManagerFactory getEntityManagerFactory();

    CriteriaBuilder getCriteriaBuilder();

    Metamodel getMetamodel();

    <T> EntityGraph<T> createEntityGraph(Class<T> var1);

    EntityGraph<?> createEntityGraph(String var1);

    EntityGraph<?> getEntityGraph(String var1);

    <T> List<EntityGraph<? super T>> getEntityGraphs(Class<T> var1);
}

 2、EntityManagerFactory 持久化工厂,可以生成多个EntityManager

The main role of an EntityManagerFactory instance is to support instantiation of EntityManager instances. An EntityManagerFactory is constructed for a specific database, and by managing resources efficiently (e.g. a pool of sockets), it provides an efficient way to construct multiple EntityManager instances for that database. 

EntityManagerFactory 是线程安全的,因此单个实​​例可以被多个线程共享;

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package javax.persistence;

import java.util.Map;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.metamodel.Metamodel;

public interface EntityManagerFactory {
    EntityManager createEntityManager();

    EntityManager createEntityManager(Map var1);

    EntityManager createEntityManager(SynchronizationType var1);

    EntityManager createEntityManager(SynchronizationType var1, Map var2);

    CriteriaBuilder getCriteriaBuilder();

    Metamodel getMetamodel();

    boolean isOpen();

    void close();

    Map<String, Object> getProperties();

    Cache getCache();

    PersistenceUnitUtil getPersistenceUnitUtil();

    void addNamedQuery(String var1, Query var2);

    <T> T unwrap(Class<T> var1);

    <T> void addNamedEntityGraph(String var1, EntityGraph<T> var2);
}

参考:

https://www.jianshu.com/p/091360c47e6b

https://www.logicbig.com/tutorials/java-ee-tutorial/jpa/entity-context.html

https://dzone.com/articles/jpa-entitymanagerfactory-interface-with-example

### 原理 `EntityManager` lookup 的原理基于 Java 的命名和目录接口(JNDI)以及 Java Persistence API(JPA)的上下文管理机制。JNDI 提供了一种统一的方式来查找和访问各种资源,包括 `EntityManagerFactory`。在 JPA 中,`EntityManagerFactory` 是创建 `EntityManager` 的工厂,通过 JNDI 可以从应用服务器的命名空间中获取已经配置好的 `EntityManagerFactory` 实例。当需要使用 `EntityManager` 进行数据库操作时,从 `EntityManagerFactory` 中获取一个 `EntityManager` 实例,该实例与特定的持久化上下文相关联,用于管理实体对象的生命周期和与数据库的交互。 ### 使用方法 #### 1. 配置 JNDI 在应用服务器中配置 `EntityManagerFactory` 的 JNDI 名称。不同的应用服务器配置方式不同,例如在 Tomcat 中可以通过配置 `context.xml` 文件来指定 JNDI 资源。 #### 2. 使用 Spring jee 命名空间进行查找 如果使用 Spring 框架,可以使用 jee 命名空间下的 `jee:jndi-lookup` 元素来获取对 `EntityManagerFactory` 的引用: ```xml <jee:jndi-lookup id="entityManagerFactory" jndi-name="java:/comp/env/persistence/MyEntityManagerFactory"/> ``` #### 3. 获取 `EntityManager` 实例 从 `EntityManagerFactory` 中获取 `EntityManager` 实例: ```java import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class MyService { @Autowired private EntityManagerFactory entityManagerFactory; public void performDatabaseOperation() { EntityManager entityManager = entityManagerFactory.createEntityManager(); try { // 开始事务 entityManager.getTransaction().begin(); // 执行数据库操作 // ... // 提交事务 entityManager.getTransaction().commit(); } catch (Exception e) { // 回滚事务 if (entityManager.getTransaction().isActive()) { entityManager.getTransaction().rollback(); } e.printStackTrace(); } finally { // 关闭 EntityManager entityManager.close(); } } } ``` ### 在本地调用场景下的应用 在本地调用场景下,当应用程序部署在应用服务器中时,`EntityManager` lookup 可以简化资源的获取过程。通过 JNDI 查找 `EntityManagerFactory`,可以避免在代码中硬编码数据库连接信息,提高代码的可维护性和可移植性。同时,使用 Spring 框架的 `jee:jndi-lookup` 元素可以方便地与 Spring 的依赖注入机制集成,使得 `EntityManagerFactory` 可以作为一个 Bean 被注入到需要使用的组件中。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值