摘要:從好的方面來說,只需使用普通的就可以在不使用文件的情況下引導(dǎo)實(shí)現(xiàn)。請(qǐng)注意,為簡(jiǎn)潔起見,我們省略了類案例結(jié)論在本文中,我們展示了如何使用的接口和的類的自定義實(shí)現(xiàn)以編程方式引導(dǎo)實(shí)體管理器,而不必依賴傳統(tǒng)的文件。
案例概述
大多數(shù)JPA驅(qū)動(dòng)的應(yīng)用程序大量使用“persistence.xml”文件來獲取JPA實(shí)現(xiàn),例如Hibernate或OpenJPA。
我們的方法提供了一種集中式機(jī)制,用于配置一個(gè)或多個(gè)持久性單元 和相關(guān)的持久性上下文。
雖然這種方法本身并不是錯(cuò)誤的,但它并不適用于需要多帶帶測(cè)試使用不同持久性單元的應(yīng)用程序組件的用例。
從好的方面來說,只需使用普通的Java就可以在不使用“persistence.xml”文件的情況下引導(dǎo)JPA實(shí)現(xiàn)。
在本文中,我們將看到如何使用Hibernate完成此任務(wù)。
實(shí)現(xiàn)PersistenceUnitInfo接口
在典型的“基于xml”的JPA配置中,JPA實(shí)現(xiàn)自動(dòng)負(fù)責(zé)實(shí)現(xiàn)PersistenceUnitInfo接口。
使用通過解析“persistence.xml”文件收集的所有數(shù)據(jù),持久性提供程序使用此實(shí)現(xiàn)來創(chuàng)建實(shí)體管理器工廠。從這個(gè)工廠,我們可以獲得一個(gè)實(shí)體。
由于我們不依賴于“persistence.xml”文件,我們需要做的第一件事就是提供我們自己的PersistenceUnitInfo實(shí)現(xiàn)。我們將Hibernate用于持久性提供程序:
public class HibernatePersistenceUnitInfo implements PersistenceUnitInfo { ????? ????public static String JPA_VERSION = "2.1"; ????private String persistenceUnitName; ????private PersistenceUnitTransactionType transactionType ??????= PersistenceUnitTransactionType.RESOURCE_LOCAL; ????private ListmanagedClassNames; ????private List mappingFileNames = new ArrayList<>(); ????private Properties properties; ????private DataSource jtaDataSource; ????private DataSource nonjtaDataSource; ????private List transformers = new ArrayList<>(); ????? ????public HibernatePersistenceUnitInfo( ??????String persistenceUnitName, List managedClassNames, Properties properties) { ????????this.persistenceUnitName = persistenceUnitName; ????????this.managedClassNames = managedClassNames; ????????this.properties = properties; ????} ? ????// standard setters / getters?? }
簡(jiǎn)而言之,HibernatePersistenceUnitInfo類只是一個(gè)普通的數(shù)據(jù)容器,它存儲(chǔ)綁定到特定持久性單元的配置參數(shù)。這包括持久性單元名稱,管理實(shí)體類的名稱,事務(wù)類型,JTA和非JTA數(shù)據(jù)源等。
使用Hibernate的EntityManagerFactoryBuilderImpl類創(chuàng)建實(shí)體管理器工廠
現(xiàn)在我們已經(jīng)實(shí)現(xiàn)了自定義PersistenceUnitInfo實(shí)現(xiàn),我們需要做的最后一件事就是獲得一個(gè)實(shí)體管理器工廠。
Hibernate使用EntityManagerFactoryBuilderImpl類(構(gòu)建器模式的簡(jiǎn)潔實(shí)現(xiàn))使這個(gè)過程變得輕而易舉。
為了提供更高級(jí)別的抽象,讓我們創(chuàng)建一個(gè)包含EntityManagerFactoryBuilderImpl功能的類。
首先,讓我們展示使用Hibernate的EntityManagerFactoryBuilderImpl類和 HibernatePersistenceUnitInf類創(chuàng)建實(shí)體管理器工廠和實(shí)體管理器的方法 :
public class JpaEntityManagerFactory { ????private String DB_URL = "jdbc:mysql://databaseurl"; ????private String DB_USER_NAME = "username"; ????private String DB_PASSWORD = "password"; ????private Class[] entityClasses; ????? ????public JpaEntityManagerFactory(Class[] entityClasses) { ????????this.entityClasses = entityClasses; ????} ????? ????public EntityManager getEntityManager() { ????????return getEntityManagerFactory().createEntityManager(); ????} ????? ????protected EntityManagerFactory getEntityManagerFactory() { ????????PersistenceUnitInfo persistenceUnitInfo = getPersistenceUnitInfo( ??????????getClass().getSimpleName()); ????????Mapconfiguration = new HashMap<>(); ????????return new EntityManagerFactoryBuilderImpl( ??????????new PersistenceUnitInfoDescriptor(persistenceUnitInfo), configuration) ??????????.build(); ????} ????? ????protected HibernatePersistenceUnitInfo getPersistenceUnitInfo(String name) { ????????return new HibernatePersistenceUnitInfo(name, getEntityClassNames(), getProperties()); ????} ? ????// additional methods }
接下來,讓我們看一下提供EntityManagerFactoryBuilderImpl和HibernatePersistenceUnitInfo所需參數(shù)的方法 。
這些參數(shù)包括托管實(shí)體類,實(shí)體類的名稱,Hibernate的配置屬性和MysqlDataSource對(duì)象:
public class JpaEntityManagerFactory { ????//... ????? ????protected ListgetEntityClassNames() { ????????return Arrays.asList(getEntities()) ??????????.stream() ??????????.map(Class::getName) ??????????.collect(Collectors.toList()); ????} ????? ????protected Properties getProperties() { ????????Properties properties = new Properties(); ????????properties.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect"); ????????properties.put("hibernate.id.new_generator_mappings", false); ????????properties.put("hibernate.connection.datasource", getMysqlDataSource()); ????????return properties; ????} ????? ????protected Class[] getEntities() { ????????return entityClasses; ????} ????? ????protected DataSource getMysqlDataSource() { ????????MysqlDataSource mysqlDataSource = new MysqlDataSource(); ????????mysqlDataSource.setURL(DB_URL); ????????mysqlDataSource.setUser(DB_USER_NAME); ????????mysqlDataSource.setPassword(DB_PASSWORD); ????????return mysqlDataSource; ????} }
為簡(jiǎn)單起見,我們?cè)贘paEntityManagerFactory類中對(duì)數(shù)據(jù)庫連接參數(shù)進(jìn)行了硬編碼。但是,在生產(chǎn)中,我們應(yīng)該將它們存儲(chǔ)在多帶帶的屬性文件中。
此外,getMysqlDataSource()方法返回一個(gè)完全初始化的MysqlDataSource對(duì)象。
我們這樣做只是為了讓事情更容易理解。在一種更實(shí)際、松耦合的設(shè)計(jì)中,我們將使用EntityManagerFactoryBuilderImpl的withDataSource()方法注入數(shù)據(jù)源對(duì)象,而不是在類中創(chuàng)建它。
使用實(shí)體管理器執(zhí)行CRUD操作
最后,讓我們看看如何使用JpaEntityManagerFactory實(shí)例獲取JPA實(shí)體管理器并執(zhí)行CRUD操作。(請(qǐng)注意,為簡(jiǎn)潔起見,我們省略了User類):
public static void main(String[] args) { ????EntityManager entityManager = getJpaEntityManager(); ????User user = entityManager.find(User.class, 1); ????? ????entityManager.getTransaction().begin(); ????user.setName("John"); ????user.setEmail("john@domain.com"); ????entityManager.merge(user); ????entityManager.getTransaction().commit(); ????? ????entityManager.getTransaction().begin(); ????entityManager.persist(new User("Monica", "monica@domain.com")); ????entityManager.getTransaction().commit(); ?? ????// additional CRUD operations } ? private static class EntityManagerHolder { ????private static final EntityManager ENTITY_MANAGER = new JpaEntityManagerFactory( ??????new Class[]{User.class}) ??????.getEntityManager(); } ? public static EntityManager getJpaEntityManager() { ????return EntityManagerHolder.ENTITY_MANAGER; }
案例結(jié)論
在本文中,我們展示了如何使用JPA的PersistenceUnitInfo接口和Hibernate的EntityManagerFactoryBuilderImpl類的自定義實(shí)現(xiàn)以編程方式引導(dǎo)JPA實(shí)體管理器,而不必依賴傳統(tǒng)的“persistence.xml”文件。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/73187.html
摘要:此的功能是從應(yīng)用程序中隱藏在底層存儲(chǔ)機(jī)制中執(zhí)行操作所涉及的所有復(fù)雜性。這正是模式試圖解決的問題。將模式與一起使用開發(fā)人員普遍認(rèn)為的發(fā)布將模式的功能降級(jí)為零,因?yàn)樵撃J街皇菍?shí)體經(jīng)理提供的另一層抽象和復(fù)雜性。在這種情況下,模式有其自己的位置。 案例概述 數(shù)據(jù)訪問對(duì)象(DAO)模式是一種結(jié)構(gòu)模式,它允許我們使用抽象API將應(yīng)用程序/業(yè)務(wù)層與持久層(通常是關(guān)系數(shù)據(jù)庫,但它可以是任何其他持久性機(jī)...
摘要:距離重磅正式發(fā)布已經(jīng)過去大半年了,而在月底就發(fā)布了,我們來看下都更新了什么,每一個(gè)技術(shù)人都值得關(guān)注。性能提升應(yīng)用程序性能改進(jìn)性能作為團(tuán)隊(duì)持續(xù)努力的一部分,性能提升在中取得了一些重大進(jìn)展。 距離《重磅:Spring Boot 2.0 正式發(fā)布!》已經(jīng)過去大半年了,而 Spring Boot 2.1.0 在 10 月底就發(fā)布了,我們來看下 Spring Boot 2.1.0 都更新了什么,...
摘要:不管是還是,表之間的連接查詢,被映射為實(shí)體類之間的關(guān)聯(lián)關(guān)系,這樣,如果兩個(gè)實(shí)體類之間沒有實(shí)現(xiàn)關(guān)聯(lián)關(guān)系,你就不能把兩個(gè)實(shí)體或者表起來查詢。 因?yàn)轫?xiàng)目需要選擇數(shù)據(jù)持久化框架,看了一下主要幾個(gè)流行的和不流行的框架,對(duì)于復(fù)雜業(yè)務(wù)系統(tǒng),最終的結(jié)論是,JOOQ是總體上最好的,可惜不是完全免費(fèi),最終選擇JDBC Template。 Hibernate和Mybatis是使用最多的兩個(gè)主流框架,而JOO...
摘要:會(huì)警告該插件未簽名。以上命令告訴創(chuàng)建一個(gè)名為的項(xiàng)目,使用包。的工具使從部署應(yīng)用非常方便。域名構(gòu)成了分配給應(yīng)用的的一部分。這將為我們創(chuàng)建一個(gè)應(yīng)用容器,自動(dòng)配置和。同時(shí)將創(chuàng)建一個(gè)私有的倉庫并克隆到本地。 編者注:我們發(fā)現(xiàn)了有趣的系列文章《30天學(xué)習(xí)30種新技術(shù)》,正在翻譯,一天一篇更新,年終禮包。下面是第 17 天的內(nèi)容。 今天的30天學(xué)習(xí)30種新技術(shù)挑戰(zhàn),我決定學(xué)習(xí)一下JBoss ...
摘要:是一門最近比較流行的靜態(tài)類型編程語言,而且和一樣同屬系。這個(gè)生成的構(gòu)造函數(shù)是合成的,因此不能從或中直接調(diào)用,但可以使用反射調(diào)用。 showImg(https://segmentfault.com/img/remote/1460000012958496); Kotlin是一門最近比較流行的靜態(tài)類型編程語言,而且和Groovy、Scala一樣同屬Java系。Kotlin具有的很多靜態(tài)語言...
閱讀 2878·2023-04-25 22:51
閱讀 2247·2021-10-11 10:58
閱讀 3383·2019-08-30 10:49
閱讀 1943·2019-08-29 17:09
閱讀 3191·2019-08-29 10:55
閱讀 903·2019-08-26 10:34
閱讀 3622·2019-08-23 17:54
閱讀 1044·2019-08-23 16:06