摘要:從好的方面來說,只需使用普通的就可以在不使用文件的情況下引導(dǎo)實現(xiàn)。請注意,為簡潔起見,我們省略了類案例結(jié)論在本文中,我們展示了如何使用的接口和的類的自定義實現(xiàn)以編程方式引導(dǎo)實體管理器,而不必依賴傳統(tǒng)的文件。
案例概述
大多數(shù)JPA驅(qū)動的應(yīng)用程序大量使用“persistence.xml”文件來獲取JPA實現(xiàn),例如Hibernate或OpenJPA。
我們的方法提供了一種集中式機制,用于配置一個或多個持久性單元 和相關(guān)的持久性上下文。
雖然這種方法本身并不是錯誤的,但它并不適用于需要多帶帶測試使用不同持久性單元的應(yīng)用程序組件的用例。
從好的方面來說,只需使用普通的Java就可以在不使用“persistence.xml”文件的情況下引導(dǎo)JPA實現(xiàn)。
在本文中,我們將看到如何使用Hibernate完成此任務(wù)。
實現(xiàn)PersistenceUnitInfo接口
在典型的“基于xml”的JPA配置中,JPA實現(xiàn)自動負(fù)責(zé)實現(xiàn)PersistenceUnitInfo接口。
使用通過解析“persistence.xml”文件收集的所有數(shù)據(jù),持久性提供程序使用此實現(xiàn)來創(chuàng)建實體管理器工廠。從這個工廠,我們可以獲得一個實體。
由于我們不依賴于“persistence.xml”文件,我們需要做的第一件事就是提供我們自己的PersistenceUnitInfo實現(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?? }
簡而言之,HibernatePersistenceUnitInfo類只是一個普通的數(shù)據(jù)容器,它存儲綁定到特定持久性單元的配置參數(shù)。這包括持久性單元名稱,管理實體類的名稱,事務(wù)類型,JTA和非JTA數(shù)據(jù)源等。
使用Hibernate的EntityManagerFactoryBuilderImpl類創(chuàng)建實體管理器工廠
現(xiàn)在我們已經(jīng)實現(xiàn)了自定義PersistenceUnitInfo實現(xiàn),我們需要做的最后一件事就是獲得一個實體管理器工廠。
Hibernate使用EntityManagerFactoryBuilderImpl類(構(gòu)建器模式的簡潔實現(xiàn))使這個過程變得輕而易舉。
為了提供更高級別的抽象,讓我們創(chuàng)建一個包含EntityManagerFactoryBuilderImpl功能的類。
首先,讓我們展示使用Hibernate的EntityManagerFactoryBuilderImpl類和 HibernatePersistenceUnitInf類創(chuàng)建實體管理器工廠和實體管理器的方法 :
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ù)包括托管實體類,實體類的名稱,Hibernate的配置屬性和MysqlDataSource對象:
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; ????} }
為簡單起見,我們在JpaEntityManagerFactory類中對數(shù)據(jù)庫連接參數(shù)進行了硬編碼。但是,在生產(chǎn)中,我們應(yīng)該將它們存儲在多帶帶的屬性文件中。
此外,getMysqlDataSource()方法返回一個完全初始化的MysqlDataSource對象。
我們這樣做只是為了讓事情更容易理解。在一種更實際、松耦合的設(shè)計中,我們將使用EntityManagerFactoryBuilderImpl的withDataSource()方法注入數(shù)據(jù)源對象,而不是在類中創(chuàng)建它。
使用實體管理器執(zhí)行CRUD操作
最后,讓我們看看如何使用JpaEntityManagerFactory實例獲取JPA實體管理器并執(zhí)行CRUD操作。(請注意,為簡潔起見,我們省略了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("[email protected]"); ????entityManager.merge(user); ????entityManager.getTransaction().commit(); ????? ????entityManager.getTransaction().begin(); ????entityManager.persist(new User("Monica", "[email protected]")); ????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類的自定義實現(xiàn)以編程方式引導(dǎo)JPA實體管理器,而不必依賴傳統(tǒng)的“persistence.xml”文件。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/73187.html
摘要:此的功能是從應(yīng)用程序中隱藏在底層存儲機制中執(zhí)行操作所涉及的所有復(fù)雜性。這正是模式試圖解決的問題。將模式與一起使用開發(fā)人員普遍認(rèn)為的發(fā)布將模式的功能降級為零,因為該模式只是實體經(jīng)理提供的另一層抽象和復(fù)雜性。在這種情況下,模式有其自己的位置。 案例概述 數(shù)據(jù)訪問對象(DAO)模式是一種結(jié)構(gòu)模式,它允許我們使用抽象API將應(yīng)用程序/業(yè)務(wù)層與持久層(通常是關(guān)系數(shù)據(jù)庫,但它可以是任何其他持久性機...
摘要:距離重磅正式發(fā)布已經(jīng)過去大半年了,而在月底就發(fā)布了,我們來看下都更新了什么,每一個技術(shù)人都值得關(guān)注。性能提升應(yīng)用程序性能改進性能作為團隊持續(xù)努力的一部分,性能提升在中取得了一些重大進展。 距離《重磅:Spring Boot 2.0 正式發(fā)布!》已經(jīng)過去大半年了,而 Spring Boot 2.1.0 在 10 月底就發(fā)布了,我們來看下 Spring Boot 2.1.0 都更新了什么,...
摘要:不管是還是,表之間的連接查詢,被映射為實體類之間的關(guān)聯(lián)關(guān)系,這樣,如果兩個實體類之間沒有實現(xiàn)關(guān)聯(lián)關(guān)系,你就不能把兩個實體或者表起來查詢。 因為項目需要選擇數(shù)據(jù)持久化框架,看了一下主要幾個流行的和不流行的框架,對于復(fù)雜業(yè)務(wù)系統(tǒng),最終的結(jié)論是,JOOQ是總體上最好的,可惜不是完全免費,最終選擇JDBC Template。 Hibernate和Mybatis是使用最多的兩個主流框架,而JOO...
摘要:會警告該插件未簽名。以上命令告訴創(chuàng)建一個名為的項目,使用包。的工具使從部署應(yīng)用非常方便。域名構(gòu)成了分配給應(yīng)用的的一部分。這將為我們創(chuàng)建一個應(yīng)用容器,自動配置和。同時將創(chuàng)建一個私有的倉庫并克隆到本地。 編者注:我們發(fā)現(xiàn)了有趣的系列文章《30天學(xué)習(xí)30種新技術(shù)》,正在翻譯,一天一篇更新,年終禮包。下面是第 17 天的內(nèi)容。 今天的30天學(xué)習(xí)30種新技術(shù)挑戰(zhàn),我決定學(xué)習(xí)一下JBoss ...
摘要:是一門最近比較流行的靜態(tài)類型編程語言,而且和一樣同屬系。這個生成的構(gòu)造函數(shù)是合成的,因此不能從或中直接調(diào)用,但可以使用反射調(diào)用。 showImg(https://segmentfault.com/img/remote/1460000012958496); Kotlin是一門最近比較流行的靜態(tài)類型編程語言,而且和Groovy、Scala一樣同屬Java系。Kotlin具有的很多靜態(tài)語言...
閱讀 2825·2023-04-25 22:51
閱讀 2084·2021-10-11 10:58
閱讀 3323·2019-08-30 10:49
閱讀 1889·2019-08-29 17:09
閱讀 3147·2019-08-29 10:55
閱讀 855·2019-08-26 10:34
閱讀 3514·2019-08-23 17:54
閱讀 997·2019-08-23 16:06