赞
踩
项目近期有个需求,要同时连接两个数据库,并且不同环境,数据库种类还不同,我们有两个数据库,其中一个测试环境是oracle,生产环境又是postgre,另一个一直是postgre,调查了网上能搜到很多资料,基本上写法都一致,比如https://blog.csdn.net/itguangit/article/details/78747969,但用在sb 2.3上会发现两个问题,一个是EntityManagerFactoryBuilder在启动时无法自动注入,虽然理论上sb会自动创建其实例,另一个是2.3中jpaProperties已经没有getHibernateProperties这个方法了,花了两天时间,发现一个外国人写的帖子方法是适用于2.3这个版本的,发布时间是去年,比较新,原帖见https://springframework.guru/how-to-configure-multiple-data-sources-in-a-spring-boot-application/ ,但也不是没有问题,需要再改造一下才能完全适应项目开发,下面是改造后的大致的代码
- spring:
- datasource:
- first:
- url: jdbc:postgresql://localhost:5432/sample
- driverClassName: org.postgresql.Driver
- username: postgres
- password: 111
- second:
- url: jdbc:oracle:thin:@//192.168.1.100:1521/orclpdb
- driverClassName: oracle.jdbc.OracleDriver
- username: webdba
- password: 111
- jpa:
- hibernate:
- ddl-auto: none
- show-sql: true

- package com.xxx.config;
-
- import com.zaxxer.hikari.HikariDataSource;
- import org.springframework.beans.factory.annotation.Qualifier;
- import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.context.annotation.Primary;
- import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
- import org.springframework.orm.jpa.JpaTransactionManager;
- import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
- import org.springframework.transaction.PlatformTransactionManager;
- import org.springframework.transaction.annotation.EnableTransactionManagement;
-
- import javax.persistence.EntityManager;
- import javax.persistence.EntityManagerFactory;
- import javax.sql.DataSource;
-
- @Configuration
- @EnableTransactionManagement
- @EnableJpaRepositories(basePackages = "com.xxx.repo.first", //当前数据源对应的repository的包名,每个数据源应该有独立的包
- entityManagerFactoryRef = "firstEntityManagerFactory",
- transactionManagerRef= "firstTransactionManager"
- )
- public class FirstJpaConfig {
- @Bean
- @Primary
- @ConfigurationProperties("spring.datasource.first")
- public DataSourceProperties firstDataSourceProperties() {
- return new DataSourceProperties();
- }
-
- @Bean
- @Primary
- @ConfigurationProperties("spring.datasource.first.configuration")
- public DataSource firstDataSource() {
- return firstDataSourceProperties().initializeDataSourceBuilder()
- .type(HikariDataSource.class).build();
- }
-
- @Primary
- @Bean(name = "firstEntityManagerFactory")
- public LocalContainerEntityManagerFactoryBean firstEntityManagerFactory(EntityManagerFactoryBuilder builder) {
- return builder
- .dataSource(firstDataSource())
- .packages("com.xxx.entity.first") //当前数据源对应的实体的包名,每个数据源应该有独立的包
- .build();
- }
-
- @Primary
- @Bean
- public PlatformTransactionManager firstTransactionManager(
- final @Qualifier("firstEntityManagerFactory") LocalContainerEntityManagerFactoryBean firstEntityManagerFactory) {
- return new JpaTransactionManager(firstEntityManagerFactory.getObject());
- }
-
- @Primary
- @Bean(name = "firstEntityManager")
- //这个不是必须,但如果你想在service中注入一个EntityManager用于执行动态jql,这个就是必要的,否则,sb会不知道选择哪个EntityManager实例使用,每个数据源对应一个实例
- public EntityManager entityManager(@Qualifier("firstEntityManagerFactory") EntityManagerFactory factory) {
- return factory.createEntityManager();
- }
- }
-

- package com.xxx.config;
-
- import com.zaxxer.hikari.HikariDataSource;
- import org.springframework.beans.factory.annotation.Qualifier;
- import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.context.annotation.Primary;
- import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
- import org.springframework.orm.jpa.JpaTransactionManager;
- import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
- import org.springframework.transaction.PlatformTransactionManager;
- import org.springframework.transaction.annotation.EnableTransactionManagement;
-
- import javax.persistence.EntityManager;
- import javax.persistence.EntityManagerFactory;
- import javax.sql.DataSource;
-
- @Configuration
- @EnableTransactionManagement
- @EnableJpaRepositories(basePackages = "com.xxx.repo.second",
- entityManagerFactoryRef = "secondEntityManagerFactory",
- transactionManagerRef= "secondTransactionManager"
- )
- public class SecondJpaConfig {
- @Bean
- @ConfigurationProperties("spring.datasource.second")
- public DataSourceProperties secondDataSourceProperties() {
- return new DataSourceProperties();
- }
-
- @Bean
- @ConfigurationProperties("spring.datasource.second.configuration")
- public DataSource secondDataSource() {
- return secondDataSourceProperties().initializeDataSourceBuilder()
- .type(HikariDataSource.class).build();
- }
-
- @Bean(name = "secondEntityManagerFactory")
- public LocalContainerEntityManagerFactoryBean secondEntityManagerFactory(EntityManagerFactoryBuilder builder) {
- return builder
- .dataSource(secondDataSource())
- .packages("com.xxx.entity.second")
- .build();
- }
-
- @Bean
- public PlatformTransactionManager secondTransactionManager(
- final @Qualifier("secondEntityManagerFactory") LocalContainerEntityManagerFactoryBean secondEntityManagerFactory) {
- return new JpaTransactionManager(secondEntityManagerFactory.getObject());
- }
-
- @Bean(name = "secondEntityManager")
- public EntityManager entityManager(@Qualifier("secondEntityManagerFactory") EntityManagerFactory factory) {
- return factory.createEntityManager();
- }
- }
-

原帖中使用的数据源实现类是dbcp,听说目前性能最好的是Hikari数据源,我就替换了一下,测试运行良好。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。