1. 程式人生 > >springboot+jpa 實現不同資料庫的多資料來源配置

springboot+jpa 實現不同資料庫的多資料來源配置

廢話不多說,直接看配置!

1、application.yml

# 多資料來源配置
#primary
spring:
  primary:
    datasource:
      url: jdbc:mysql://xxx.xxx.xxx.xxx:3306/dico_dev?autoReconnect=true&autoReconnectForPools=true&useUnicode=true&characterEncoding=UTF-8&useSSL=true
      username: root
      password: xxxx
      driver-class-name: com.mysql.jdbc.Driver

#secondary
  secondary:
    datasource:
      url: jdbc:sqlserver://xxx.xxx.xxxx.xxx:1433;databasename=LZMISportal
      username: root
      password: xxxx
      driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver

  jpa:
    hibernate:
      primary-dialect: org.hibernate.dialect.MySQL5Dialect
      secondary-dialect: org.hibernate.dialect.SQLServer2008Dialect
    open-in-view: true
    show-sql: true

配置檔案如上,分別定義兩個資料庫的連結和資料庫對應的方言。

2、配置資料來源

@Configuration
public class DataSourceConfig {


    @Bean(name = "primaryDataSource")
    @Primary
    @Qualifier("primaryDataSource")
    @ConfigurationProperties(prefix = "spring.primary.datasource")
    public DataSource primaryDatasource() {
        return DataSourceBuilder.create().build();
    }

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

}

程式碼解析:1、兩個資料來源分別對應yml檔案中配置的資料來源 2、使用@Bean註解將對應方法釋出以供後邊使用

3、定義不同資料來源的作用域

多資料來源配置 1)

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "entityManagerFactoryPrimary",//配置連線工廠 entityManagerFactory
        transactionManagerRef = "transactionManagerPrimary", //配置 事物管理器  transactionManager
        basePackages = {"xxx.xxx.xxx.xxx","xxx.xxx.xxx.xxx","xxx.xxx.xxx.xxx","xxx.xxx.xxx.xxx","xxx.xxx.xxx.xxx"}//設定持久層所在位置
)
public class PrimaryConfig {

    @Autowired
    private JpaProperties jpaProperties;

    @Autowired
    @Qualifier("primaryDataSource")
    private DataSource primaryDataSource;// 自動注入配置好的資料來源
    
    @Value("${spring.jpa.hibernate.primary-dialect}")
    private String primaryDialect;// 獲取對應的資料庫方言


    /**
     *
     * @param builder
     * @return
     */
    @Bean(name = "entityManagerFactoryPrimary")
    @Primary
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {

        return builder
                //設定資料來源
                .dataSource(primaryDataSource)
                //設定資料來源屬性
                .properties(getVendorProperties(primaryDataSource))
                //設定實體類所在位置.掃描所有帶有 @Entity 註解的類
                .packages("xxx.xxx.xxx.xxx","xxx.xxx.xxx.xxx","xxx.xxx.xxx.xxx","xxx.xxx.xxx.xxx","xxx.xxx.xxx.xxx")
                // Spring會將EntityManagerFactory注入到Repository之中.有了 EntityManagerFactory之後,
                // Repository就能用它來建立 EntityManager 了,然後 EntityManager 就可以針對資料庫執行操作
                .persistenceUnit("primaryPersistenceUnit")
                .build();

    }

    private Map<String, String> getVendorProperties(DataSource dataSource) {
        Map<String,String> map = new HashMap<>();
        map.put("hibernate.dialect",primaryDialect);// 設定對應的資料庫方言
        jpaProperties.setProperties(map);
        return jpaProperties.getHibernateProperties(dataSource);
    }

    /**
     * 配置事物管理器
     *
     * @param builder
     * @return
     */
    @Bean(name = "transactionManagerPrimary")
    @Primary
    PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
    }


}

多資料來源配置 2)

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef="entityManagerFactorySecondary",
        transactionManagerRef="transactionManagerSecondary",
        basePackages= { "xxx.xxx.xxx.xxx" })
public class SecondaryConfig {

    @Autowired
    private JpaProperties jpaProperties;

    @Autowired
    @Qualifier("secondaryDataSource")
    private DataSource secondaryDataSource;
    
    @Value("${spring.jpa.hibernate.secondary-dialect}")
    private String secondaryDialect;



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

    @Bean(name = "entityManagerFactorySecondary")
    public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary (EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(secondaryDataSource)
                .properties(getVendorProperties(secondaryDataSource))
                .packages("xxx.xxx.xxx.xxx")
                .persistenceUnit("secondaryPersistenceUnit")
                .build();
    }

    private Map<String, String> getVendorProperties(DataSource dataSource) {
        Map<String,String> map = new HashMap<>();
        map.put("hibernate.dialect",secondaryDialect);
        jpaProperties.setProperties(map);
        return jpaProperties.getHibernateProperties(dataSource);
    }

    @Bean(name = "transactionManagerSecondary")
    PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
    }


}

至此,所有配置已完成,配置掃描到的所有@Entity類將被對應到不同的資料庫中。