JPA 实体管理器工厂(EntityManagerFactory)

2024-08-27 08:18

本文主要是介绍JPA 实体管理器工厂(EntityManagerFactory),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://huangliangbao.iteye.com/blog/806531
通过上一节讲述,可以看到实体管理器工厂 EntityManagerFactory是获得实体管理器EntityManager对象的入口,而EntityManagerFactory对象是通过javax.persistenc.Persistence类中的静态方法createEntityManagerFactory来创建的。  

例如下面代码所示。  

EntityManagerFactory emf =  

javax.persistence.Persistence.createEntityManagerFactory("jpaUnit");  

EntityManager em = emf.createEntityManager();  

下面首先详细了解一下javax.persistenc.Persistence类中的API。  

11.2.1  javax.persistenc.Persistence API  
javax.persistenc.Persistence类提供了两个手动创建EntityManagerFactory对象的方法,它们的定义如下所示。  

package javax.persistence;  

import java.util.*;  

public class Persistence {  

      

    public static EntityManagerFactory createEntityManagerFactory(  

    String persistenceUnitName) {...}  

      

    public static EntityManagerFactory createEntityManagerFactory(  

    String persistenceUnitName, Map properties) {...}  

}  

其中,createEntityManagerFactory(String persistenceUnitName, Map properties)方法中properties的参数将覆盖persistence.xml文件配置的参数。  

例如persistence.xml中的<property>元素中的配置如下所示。  

<?xml version="1.0" encoding="UTF-8"?>  

<persistence>  

    <persistence-unit name="jpaUnit" transaction-type="RESOURCE_LOCAL">  

        <provider>org.hibernate.ejb.HibernatePersistence</provider>  

        <properties>子  

            <property name = "hibernate.connection.driver_class" value = "com.mysql. jdbc.Dr iver"/>  

            <property name = "hibernate.connection.url" value = "jdbc:mysql: //localhost:3306/jp ademo"/>  

            <property name = "hibernate.connection.username" value = "root"/>  

        </properties>  

        <property name="hibernate.show_sql" value="true" />  

    </persistence-unit>  

</persistence>  

其中,属性 hibernate.show_sql的值为true,若创建EntityManagerFactory对象时采用以下的代码,则实际获得的 EntityManagerFactory对象属性hibernate.show_sql则为false,即为代码中所设置的将覆盖配置文件中所配置的,如下所示。  

Map properties = new HashMap();  

properties.put("hibernate.show_sql", "false");  

EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpaUnit", properties);  

11.2.2  EntityManagerFactory API  
上一节创建了EntityManagerFactory对象,那么如何使用EntityManagerFactory对象创建EntityManager对象呢?下面来看EntityManagerFactory的定义,如下所示。  

public interface javax.persistence.EntityManagerFactory {  

      

    public EntityManager createEntityManager();  

      

    public EntityManager createEntityManager(Map map);  

      

    public void close();  

      

    public boolean isOpen();  

}  

在创建EntityManagerFactory对象后,使用完后应该及时关闭。所以使用创建Entity ManagerFactory的代码如下所示。  

EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpaUnit");  

EntityManager entityManager = emf.createEntityManager();  

 

entityManager.close();  

emf.close();  

11.2.3  实现自己的JPA  
细心的读者可能会有疑问,为什么如下的简单代码就可以创建名称为“jpaUnit”的EntityManagerFactory对象呢?  

EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpaUnit");  

虽然这部分内容在使用JPA时并不需要了解,但如果读者想要自己实现JPA规范,这些内容是必须要了解的。  

下面以笔者自己实现的简单例子,详细讲述其中的原理。通过这个完整的例子,读者可以对JPA的实现有更深刻的理解。  

11.2.3.1  实现PersistenceProvider接口  
首先编写一个类JPAPersistence并实现javax.persistence.spi.PersistenceProvider类,代码如下所示。  

package com.fengmanfei.jpa;  

import java.util.Map;  

import javax.persistence.EntityManagerFactory;  

import javax.persistence.spi.PersistenceProvider;  

import javax.persistence.spi.PersistenceUnitInfo;  

public class JPAPersistence implements PersistenceProvider {  

      

    public EntityManagerFactory createContainerEntityManagerFactory(  

            PersistenceUnitInfo persistenceunitinfo, Map map) {  

          

        System.out.println(this.getClass().getName()  

                + ".createContainerEntityManagerFactory"  

                + "(PersistenceUnitInfo persistenceunitinfo,Map map)自己实现的方法");  

        return new EntityManagerFactoryImpl();  

    }  

      

    public EntityManagerFactory createEntityManagerFactory(String s, Map map) {  

          

        System.out.println(this.getClass().getName()  

                + ".createContainerEntityManagerFactory"  

                + "(String s, Map map)自己实现的方法");  

        return new EntityManagerFactoryImpl();  

    }  

}  

由于这里只是简单地说明如何初始化JPA的实现,所以只打印出调用方法的信息,并返回EntityManagerFactoryImpl对象。  

11.2.3.2  实现EntityManagerFactory接口  
然后编写一个简单的实现EntityManagerFactory接口的类EntityManagerFactoryImpl,代码如下所示。  

package com.fengmanfei.jpa;  

import java.util.Map;  

import javax.persistence.EntityManager;  

import javax.persistence.EntityManagerFactory;  

public class EntityManagerFactoryImpl implements EntityManagerFactory {  

    public void close() {  

          

    }  

    public EntityManager createEntityManager() {  

          

        return null;  

    }  

    public EntityManager createEntityManager(Map map) {  

          

        return null;  

    }  

    public boolean isOpen() {  

          

        return false;  

    }  

}  

其中,这里接口中的方法笔者并没有编写自己的实现,读者如果需要可以自己添加代码。对于这里所实现的 javax.persistence.spi.PersistenceProvide类所在的包,可以通过JPA的官方网站下载,也可以从 “JBOSS_HOME\server\default\lib”目录下的ejb3-persistence.jar包中获得,在编译时要将这个类包添加到构建路径中。  

11.2.3.3  定义自己的实现类  
在META-INF文件目录下创建services\javax.persistence.spi.PersistenceProvider文件,在该文件中输入实现PersistenceProvider接口类的全名,如下所示。  

com.fengmanfei.jpa.JPAPersistence  


修改persistence.xml中的配置如下所示。  

<?xml version="1.0" encoding="UTF-8"?>  

<persistence >  

    <persistence-unit name="jpaUnit"  

        transaction-type="RESOURCE_LOCAL">  

        <provider>com.fengmanfei.jpa.JPAPersistence</provider>  

    </persistence-unit>  

</persistence>  

其中<provider>要配置为所实现的javax.persistence.spi.PersistenceProvider接口类。这样当客户端创建“jpaUnit”EntityManagerFactory对象时,就会调用自己实现的方法。  

例如,客户端代码如下所示。  

public class CustomerClient {  

    public static void main(String[] args) {  

          

        EntityManagerFactory emf = Persistence  

                .createEntityManagerFactory("jpaUnit");  

          

    }  

}  

程序运行后,控制台将输出如下所示的运行结果。  

com.fengmanfei.jpa.JPAPersistence.createContainerEntityManagerFactory(String s, Map map)自己实现的方法  

可以看到,当调用javax.persistenc.Persistence中的createEntityManagerFactory时,运行的是com.fengmanfei.jpa.JPAPersistence中的方法,并输出了相应的结果。  

11.2.3.5  加载原理  
当调用 javax.persistenc.Persistence中的createEntityManagerFactory方法时,程序会自动查找当前类加载器中所有的META-INF/services/javax.persistence.spi.PersistenceProvider文件中定义的 JPA实现类,如果还未初始化,则首先将这些实现类实例化。如果实现类已经实例化,则根据根据“unitName”来创建对应的实现类,直到返回的 EntityManagerFactory不为null为止。  


如果读者想要更深入地了解JPA具体是如何实现的,建议读者研究一下Hibernate的源代码,这是一个很好的学习途径。  

这篇关于JPA 实体管理器工厂(EntityManagerFactory)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1111123

相关文章

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

使用Spring Boot集成Spring Data JPA和单例模式构建库存管理系统

引言 在企业级应用开发中,数据库操作是非常重要的一环。Spring Data JPA提供了一种简化的方式来进行数据库交互,它使得开发者无需编写复杂的JPA代码就可以完成常见的CRUD操作。此外,设计模式如单例模式可以帮助我们更好地管理和控制对象的创建过程,从而提高系统的性能和可维护性。本文将展示如何结合Spring Boot、Spring Data JPA以及单例模式来构建一个基本的库存管理系统

【Python知识宝库】上下文管理器与with语句:资源管理的优雅方式

🎬 鸽芷咕:个人主页  🔥 个人专栏: 《C++干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 文章目录 前言一、什么是上下文管理器?二、上下文管理器的实现三、使用内置上下文管理器四、使用`contextlib`模块五、总结 前言 在Python编程中,资源管理是一个重要的主题,尤其是在处理文件、网络连接和数据库

设计模式之工厂模式(通俗易懂--代码辅助理解【Java版】)

文章目录 1、工厂模式概述1)特点:2)主要角色:3)工作流程:4)优点5)缺点6)适用场景 2、简单工厂模式(静态工厂模式)1) 在简单工厂模式中,有三个主要角色:2) 简单工厂模式的优点包括:3) 简单工厂模式也有一些限制和考虑因素:4) 简单工厂模式适用场景:5) 简单工厂UML类图:6) 代码示例: 3、工厂方法模式1) 在工厂方法模式中,有4个主要角色:2) 工厂方法模式的工作流程

Apache Tiles 布局管理器

陈科肇 =========== 1.简介 一个免费的开源模板框架现代Java应用程序。  基于该复合图案它是建立以简化的用户界面的开发。 对于复杂的网站,它仍然最简单,最优雅的方式来一起工作的任何MVC技术。 Tiles允许作者定义页面片段可被组装成在运行一个完整的网页。  这些片段,或Tiles,可以用于为了降低公共页面元素的重复,简单地包括或嵌入在其它瓦片,制定了一系列可重复使用

工厂方法模式和抽象工厂模式的区别

区别  工厂方法模式: 一个抽象产品类,可以派生出多个具体产品类。    一个抽象工厂类,可以派生出多个具体工厂类。    每个具体工厂类只能创建一个具体产品类的实例。 抽象工厂模式: 多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。    一个抽象工厂类,可以派生出多个具体工厂类。    每个具体工厂类可以创建多个具体产品类的实例。    区别: 工厂方法模式只有一个抽象产品类

c++11工厂子类实现自注册的两种方法

文章目录 一、产品类构建1. 猫基类与各品种猫子类2.狗基类与各品种狗子类 二、工厂类构建三、客户端使用switch-case实现调用不同工厂子类四、自注册方法一:公开注册函数显式注册五、自注册方法二:构造函数隐形注册总结 一、产品类构建 1. 猫基类与各品种猫子类 class Cat {public:virtual void Printer() = 0;};class

智能工厂程序设计 之1 智能工厂都本俱的方面(Facet,Aspect和Respect)即智能依赖的基底Substrate 之1

Q1、昨天分别给出了三个智能工厂的 “面face”(里面inter-face,外面outer-face和表面surface) 以及每个“面face” 各自使用的“方”(StringProcessor,CaseFilter和ModeAdapter)  。今天我们将继续说说三个智能工厂的“方面” 。在展开之前先看一下三个单词:面向facing,取向oriented,朝向toword。理解这三个词 和

BERN2(生物医学领域)命名实体识别与命名规范化工具

BERN2: an advanced neural biomedical named entity recognition and normalization tool 《Bioinformatics》2022 1 摘要 NER和NEN:在生物医学自然语言处理中,NER和NEN是关键任务,它们使得从生物医学文献中自动提取实体(如疾病和药物)成为可能。 BERN2:BERN2是一个工具,

Qt-常用控件(3)-多元素控件、容器类控件和布局管理器

1. 多元素控件 Qt 中提供的多元素控件有: QListWidgetQListViewQTableWidgetQTableViewQTreeWidgetQTreeView xxWidget 和 xxView 之间的区别,以 QTableWidget 和 QTableView 为例. QTableView 是基于 MVC 设计的控件.QTableView 自身不持有数据,使用 QTab