SpringBoot2.0 + SpringDataJpa 配置mysql雙數據源

1、配置文件yml,筆者這裏將cdr作爲主數據源,mdc作爲次數據源。

注:如果在配置多數據源時報錯 jdbcUrl is required with driverClassName,主要原因是在1.0 配置數據源的過程中主要是寫成:url  driverClassName。而在2.0升級之後需要變更成:jdbc-url driver-class-name即可解決!

  datasource:
    cdr:
      driver-class-name: com.mysql.jdbc.Driver
      jdbc-url: jdbc:mysql://10.188.188.103:10457/cdr?useUnicode=true&characterEncoding=UTF-8&useSSL=false
      username: cdr
      password: cdr
      hikari:
        maximum-pool-size: 10
    mdc:
      driver-class-name: com.mysql.jdbc.Driver
      jdbc-url: jdbc:mysql://10.188.188.103:10457/mdc?useUnicode=true&characterEncoding=UTF-8&useSSL=false
      username: mdc
      password: mdc
      hikari:
        maximum-pool-size: 10

2、雙數據源總的配置

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;

/**
 * mysql雙數據源總的配置
 * @author sxp
 */
@Configuration
public class DataSourceConfig {

    //這裏的前綴與yml自定義的前綴保持一致,其中只能有一個@Primary用於標識主數據源
    @Bean(name="cdrDataSource")
    @Primary
    @ConfigurationProperties(prefix="spring.datasource.cdr")
    public DataSource primaryDataSource() {
       return DataSourceBuilder.create().build();
    }

    @Bean(name="mdcDataSource")
    @ConfigurationProperties(prefix="spring.datasource.mdc")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create().build();
    }
}

3、主數據源cdr 的配置

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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.jdbc.core.JdbcTemplate;
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.sql.DataSource;
import java.util.Properties;

/**
 * 主數據源cdr mysql 配置
 * @author sxp
 */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef="cdrEntityManagerFactory",
        //repository 所在路徑
        basePackages = {"org.scbit.lsbi.cdr.repository.mysql"},
        transactionManagerRef = "cdrTransactionManager")
public class CdrDataSourceConfig {

    @Autowired
    @Qualifier("cdrDataSource")
    private DataSource cdrDataSource;

    /**
     * JdbcTemplate 支持
     * @return
     */
    @Primary
    @Bean(name = "cdrJdbcTemplate")
    public JdbcTemplate primaryJdbcTemplate() {
        return new JdbcTemplate(cdrDataSource);
    }

    @Primary
    @Bean(name = "entityManagerPrimary")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
        return cdrEntityManagerFactory(builder).getObject().createEntityManager();
    }

    private Properties jpaProperties;

    /**
     * 設置實體類所在位置
     * 對@Primary修飾的LocalContainerEntityManagerFactoryBean可以不用指定TransactionManager,
     * spring上下文自動使用默認的JpaTransactionManager,但是對於第二個或第三個等等必須指定TransactionManager,筆者在實測過程中卻發現即使是@Primar修飾的也得指定TransactionManager
     */
    @Primary
    @Bean(name = "cdrEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean cdrEntityManagerFactory(EntityManagerFactoryBuilder builder) {
        LocalContainerEntityManagerFactoryBean entityManagerFactory = builder
                .dataSource(cdrDataSource)
                .packages("org.scbit.lsbi.cdr.dataobject.model")
                .persistenceUnit("primaryPersistenceUnit")
                .build();
        entityManagerFactory.setJpaProperties(jpaProperties);
        return entityManagerFactory;
    }

    @Primary
    @Bean(name = "cdrTransactionManager")
    public PlatformTransactionManager cdrTransactionManager(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(cdrEntityManagerFactory(builder).getObject());
    }

}

4、次數據源mdc 的配置

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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.jdbc.core.JdbcTemplate;
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.sql.DataSource;
import java.util.Properties;

/**
 * 次數據源mdc mysql 配置
 * @author sxp
 */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef="mdcEntityManagerFactory",
        basePackages = {"org.scbit.lsbi.mdc.mysql.repository"},
        transactionManagerRef = "mdcTransactionManager")
public class MdcDataSourceConfig {

    @Autowired
    @Qualifier("mdcDataSource")
    private DataSource mdcDataSource;

    /**
     * JdbcTemplate 支持
     * @return
     */
    @Bean(name = "mdcJdbcTemplate")
    public JdbcTemplate primaryJdbcTemplate() {
        return new JdbcTemplate(mdcDataSource);
    }

    @Primary
    @Bean(name = "entityManagerSecondary")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
        return mdcEntityManagerFactory(builder).getObject().createEntityManager();
    }

    private Properties jpaProperties;

    /**
     * 設置實體類所在位置
     * 對@Primary修飾的LocalContainerEntityManagerFactoryBean可以不用指定TransactionManager,
     * spring上下文自動使用默認的JpaTransactionManager,但是對於第二個或第三個等等必須指定TransactionManager
     */
    @Bean(name = "mdcEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean mdcEntityManagerFactory(EntityManagerFactoryBuilder builder) {
        LocalContainerEntityManagerFactoryBean entityManagerFactory = builder
                .dataSource(mdcDataSource)
                .packages("org.scbit.lsbi.mdc.mysql.model")
                .persistenceUnit("secondaryPersistenceUnit")
                .build();
        entityManagerFactory.setJpaProperties(jpaProperties);
        return entityManagerFactory;
    }

    @Primary
    @Bean(name = "mdcTransactionManager")
    public PlatformTransactionManager mdcTransactionManager(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(mdcEntityManagerFactory(builder).getObject());
    }

}

5、至此,雙數據源已配置完成,下面是jdbcTemplate、transactionManager的在項目中的具體使用:

@Autowired
@Qualifier("mdcJdbcTemplate")
private JdbcTemplate mdcJdbcTemplate;
/*
* 事務
*/
@Transactional(transactionManager = "cdrTransactionManager")
private void updateDatasetTree(CdrDataset cdrDataset, String newPid){

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章