如何在Hibernate/JPA中配置具有兩個連線池的兩個資料來源

banq發表於2019-02-26

這是展示一個SpringBoot應用程式,它使用兩個資料來源(兩個MySQL資料庫,一個命名players_db,一個命名coaches_db)和兩個連線池(每個資料庫使用自己的HikariCP連線池,具有不同的設定)。基於上述配置,從兩個不同的提供程式配置兩個連線池非常容易。

關鍵點:

1. 在pom.xml,新增spring-boot-configuration-processor依賴項

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>



2. 在application.properties,自定義兩個配置兩個HikariCP連線池,例如app.datasource.ds1和app.datasource.ds2 

app.datasource.ds1.url=jdbc:mysql://localhost:3306/players_db?createDatabaseIfNotExist=true
app.datasource.ds1.username=root
app.datasource.ds1.password=root
app.datasource.ds1.connection-timeout=50000
app.datasource.ds1.idle-timeout=300000
app.datasource.ds1.max-lifetime=900000
app.datasource.ds1.maximum-pool-size=8
app.datasource.ds1.minimum-idle=8
app.datasource.ds1.pool-name=MyPoolDS1
app.datasource.ds1.connection-test-query=select 1 from dual

app.datasource.ds2.url=jdbc:mysql://localhost:3306/coaches_db?createDatabaseIfNotExist=true
app.datasource.ds2.username=root
app.datasource.ds2.password=root
app.datasource.ds2.connection-timeout=50000
app.datasource.ds2.idle-timeout=300000
app.datasource.ds2.max-lifetime=900000
app.datasource.ds2.maximum-pool-size=4
app.datasource.ds2.minimum-idle=4
app.datasource.ds2.pool-name=MyPoolDS2
app.datasource.ds2.connection-test-query=select 1 from dual

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect

logging.level.com.zaxxer.hikari.HikariConfig=DEBUG
logging.level.com.zaxxer.hikari=TRACE

spring.jpa.show-sql=true


3. 寫一個@Bean返回第一個DataSource並將其標記為@Primary  
寫另一個@Bean返回第二個DataSource  


@Configuration
public class ConfigureDataSources {

    @Bean(name = "c1")
    @Primary
    @ConfigurationProperties("app.datasource.ds1")
    public DataSourceProperties firstDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean(name = "c2")
    @ConfigurationProperties("app.datasource.ds2")
    public DataSourceProperties secondDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean(name = "ds1")
    @Primary
    @ConfigurationProperties("app.datasource.ds1")
    public HikariDataSource firstDataSource(@Qualifier("c1") DataSourceProperties properties) {
        return properties.initializeDataSourceBuilder().type(HikariDataSource.class)
                .build();
    }

    @Bean(name = "ds2")
    @ConfigurationProperties("app.datasource.ds2")
    public HikariDataSource secondDataSource(@Qualifier("c2") DataSourceProperties properties) {
        return properties.initializeDataSourceBuilder().type(HikariDataSource.class)
                .build();
    }
}


4. 配置兩個EntityManagerFactory並指出要掃描每個包的包


@Configuration
@EnableJpaRepositories(
        entityManagerFactoryRef = "ds1EntityManagerFactory",
        transactionManagerRef = "ds1TransactionManager",
        basePackages = "com.jpa.ds1"
)
@EnableTransactionManagement
public class FirstEntityManagerFactory {

    @Bean
    @Primary
    public LocalContainerEntityManagerFactoryBean ds1EntityManagerFactory(
            EntityManagerFactoryBuilder builder, @Qualifier("ds1") DataSource dataSource) {
        return builder
                .dataSource(dataSource)
                .packages(packagesToScan())
                .persistenceUnit("ds1-pu")
                .properties(singletonMap("hibernate.hbm2ddl.auto", "create"))
                .build();
    }

    @Bean
    @Primary
    public PlatformTransactionManager ds1TransactionManager(
            @Qualifier("ds1EntityManagerFactory") EntityManagerFactory ds1EntityManagerFactory) {
        return new JpaTransactionManager(ds1EntityManagerFactory);
    }

    protected String[] packagesToScan() {
        return new String[]{
            "com.jpa.ds1"
        };
    }

}


4.將每個與EntityManager相關領域模型和儲存庫放在正確的包中:
ds1包目錄: Player.java  PlyaerRepository.java PlayerService.java
ds2包目錄:Coach.java   CoachRepository.java CoachService.java


原始碼可以在這裡找到

相關文章