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