我是Java的新手,我需要创建一个控制台应用程序,它将连接4个数据库(access,vfp,mysql和sqlserver)。
我从hibernate.cfg.xml文件开始,并设法配置它们,每个数据库一个。然后我意识到jpa是一个更好的解决方案。所以我将所有的hibernate文件更改为带有4个持久性单元的persistence.xml文件。
数据库运行良好,但要使用它们,我必须创建大量代码。这是一个例子:
EntityManagerFactory dbPersistence =
Persistence.createEntityManagerFactory("oneOfMyDatabases");
EntityManager em = dbPersistence.createEntityManager();
Query query = em.createQuery("from ProductEntity").setMaxResults(10);
for (Object o : query.getResultList()) {
ProductEntity c = (ProductEntity) o;
System.out.println("Product " + c.getName());
}
cgPersistence.close();
我需要使用其他数据库中的数据更新其中一个数据库。
创建像这样的所有代码是一件痛苦的事情,所以我在考虑创建存储库,但我无法看到如何使用不同的entityManagers为每个数据库创建存储库。
我尝试向管理员注入google guice但没有成功,但我无法处理如何关闭或在何处关闭持久性连接。
最后,我发现了Spring Data,它似乎是我需要的,但我真的不明白如何使用它。
我需要一些指南才能让它工作,因为我已经阅读了大量的教程,而且每个教程看起来都不同: ·我可以使用相同的persistence.xml,还是需要其他配置文件?我已经看到Spring Data具有jpa兼容性,但我不确定它是如何工作的。 ·Spring Context是Spring框架的IOC容器吗?我需要它来使用Spring Data吗? ·我还需要什么?
提前谢谢
答案 0 :(得分:3)
每个数据库将由不同的数据源表示。对于每个数据源,您需要一个不同的会话工厂/实体管理器工厂。
如果要在单个事务中保存多个数据源,则需要XA事务,因此需要Java EE或独立事务管理器,如Bitronix或Atomikos。
您有4个不同的实体经理工厂,您还需要每个工厂的特定存储库:
<jpa:repositories base-package="your.company.project.repository.access" entity-manager-factory-ref="accessEntityManagerFactory"/>
<jpa:repositories base-package="your.company.project.repository.sqlserver" entity-manager-factory-ref="sqlserverEntityManagerFactory"/>
然后您的应用程序不必关心它使用哪个存储库。
JpaTransactionManager需要一个entityManagerFactory,但由于你有4个,你最终可能会创建那些,我认为这是不可取的。
最好切换到JTA:
<!-- 1. You define the Bitronix config ->
<bean id="btmConfig" factory-method="getConfiguration" class="bitronix.tm.TransactionManagerServices">
<property name="serverId" value="spring-btm"/>
<property name="warnAboutZeroResourceTransaction" value="true"/>
<property name="logPart1Filename" value="${btm.config.logpart1filename}"/>
<property name="logPart2Filename" value="${btm.config.logpart2filename}"/>
<property name="journal" value="${btm.config.journal:disk}"/>
</bean>
<!-- 2. You define all your data sources ->
<bean id="dataSource" class="bitronix.tm.resource.jdbc.PoolingDataSource" init-method="init"
destroy-method="close">
<property name="className" value="${jdbc.driverClassName}"/>
<property name="uniqueName" value="dataSource"/>
<property name="minPoolSize" value="0"/>
<property name="maxPoolSize" value="5"/>
<property name="allowLocalTransactions" value="false"/>
<property name="driverProperties">
<props>
<prop key="user">${jdbc.username}</prop>
<prop key="password">${jdbc.password}</prop>
<prop key="url">${jdbc.url}</prop>
</props>
</property>
</bean>
<!-- 3. For each data source you create a new persistenceUnitManager and you give its own specific persistence.xml ->
<bean id="persistenceUnitManager" depends-on="transactionManager"
class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml"/>
<property name="defaultDataSource" ref="dataSource"/>
<property name="dataSourceLookup">
<bean class="org.springframework.jdbc.datasource.lookup.BeanFactoryDataSourceLookup"/>
</property>
</bean>
<!-- JpaDialect must be configured for transactionManager to make JPA and JDBC share transactions -->
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
<!-- 4. For each data source you create a new entityManagerFactory ->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="persistenceUnit"/>
<property name="persistenceUnitManager" ref="persistenceUnitManager"/>
<property name="jpaDialect" ref="jpaDialect"/>
</bean>
<!-- 5. You have only one JTA transaction manager ->
<bean id="jtaTransactionManager" factory-method="getTransactionManager"
class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig, dataSource"
destroy-method="shutdown"/>
<!-- 6. You have only one Spring transaction manager abstraction layer ->
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="jtaTransactionManager"/>
<property name="userTransaction" ref="jtaTransactionManager"/>
</bean>
如果这对您当前的问题证明太多工作,您可以尝试拥有4个JPA事务管理器,看看它是如何工作的。
答案 1 :(得分:0)
如果您的架构在所有数据库中都相同,那么最好的方法是使用hibernate,因为hibernate提供了多个数据库之间的可移植性。一旦你创建了hbm文件和pojo类,你唯一需要改变的就是方言和你的数据源。
可以通过spring提供transactionmanager支持。