配置雙數據源時,我們如何來進行切換?

我們在進行雙源讀寫的項目時,需要在yml文件中配置好兩個數據源,

server:
  port: 9009
eureka:
  client:
    service-url:
      defaultZone: http://localhost:9999/eureka/
    register-with-eureka: false
    fetch-registry: false
    security:
      basic:
        enabled: false
spring:
  datasource:
    fc:
      driver-class-name: oracle.jdbc.OracleDriver
      jdbc-url: jdbc:oracle:thin:@10.0.14.20:1521:stdb
      username: formicarydb
      password: formicarydb
      schema:
        - classpath:InitSql/*schema.sql
      schema-username: formicarydb
      schema-password: formicarydb
      data:
        - classpath:InitSql/*data.sql
      data-password: formicarydb
      data-username: formicarydb
      initialization-mode: always
    nc:
      driver-class-name: oracle.jdbc.OracleDriver
      jdbc-url: jdbc:oracle:thin:@10.0.14.20:1521:stdb
      username: stnc_train
      password: stnc_train
  jpa:
    show-sql: true
mybatis:
  fc:
    #config-location: classpath:/mapper/config/mybatisConfig.xml #可以注射掉,沒用到該配置文件
          mapper-locations*: classpath:mapper/FC/*Mapper.xml

#    mapper-locations: classpath:mapper/FC/FCBdMarbasclassMapper.xml
          type-aliases-package: com.siter.mapper.FC

  nc:
          mapper-locations*: classpath:mapper/NC/*Mapper.xml
#          mapper-location後面的“*”特別重要,缺少“*”號的話後面的通配符就不起作用,然後就會引起意想不到的錯誤;
#    mapper-locations: classpath:mapper/NC/BdMarbasclassMapper.xml
          type-aliases-package: com.siter.mapper.NC

#熱部署

更改完雙數據源後,我們應該分別對兩個數據源進行配置類的編寫;
首先,我們對主配置類進行編寫:

package com.siter.config;

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 org.springframework.context.annotation.PropertySource;

import javax.sql.DataSource;

@Configuration
/*在此類上使用@PropertiesSource註解尋找這個數據源配置類關聯的數據庫連接信息的配置文件的地址
 (此配置文件可以放在項目外邊,便於修改配置文件的連接信息)
 */
@PropertySource("jdbc.properties")
/**
 * 該類屬於數據源的一個配置類,主要用來綁定我們在yml文件中的數據源(綁定數據源配置);
 */
public class DataSourceConfig {
    // destroy-method="close":當數據庫連接不使用的時候,將該連接重新放到數據池中
    @Bean(name = "NC",destroyMethod = "close")
//    @Bean(name = "NC")
//    @Qualifier("NC")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.nc")
    public DataSource dataSource1() {
        return DataSourceBuilder.create().build();
    }

    //配置數據源二: destroy-method="close":當數據庫連接不使用的時候,將該連接重新放到數據池中
    @Bean(name = "FC",destroyMethod = "close")
//    @Bean(name = "FC")
//    @Qualifier("FC")
//    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.fc")
    public DataSource datasource2() {
        return DataSourceBuilder.create().build();
    }

}

後面是分別兩個數據源的配置:

package com.siter.config;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;
import java.nio.file.Path;

/**
 * 主數據源的一個配置
 */
@Configuration
//NC接口類的一些包名掃描
@MapperScan(basePackages = {"com.siter.mapper.NC"}, sqlSessionFactoryRef = "NCSqlSessionFactoryBean")
public class NcConfig {

    // 必須指定注入哪個數據源,否則找到多個會注入失敗
    @Autowired
    @Qualifier("NC")
    private DataSource db1;

    @Bean(name = "NCSqlSessionFactoryBean")
    @Primary
    @ConfigurationProperties(prefix = "mybatis.nc")
    public SqlSessionFactoryBean NCSqlSessionFactoryBean() throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        // 配置數據源
        sqlSessionFactoryBean.setDataSource(db1);
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/NC/*.xml"));
//      sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/FC/FCBdMarbasclassMapper.xml"));

        return sqlSessionFactoryBean;
    }

    // 可選,如果需要通過SqlSessionTemplate來操作持久層就通過@Bean實例化,我們這個例子中沒用到,隨手寫出來了
    @Bean(name = "NCSqlSessionTemplate")
    @Primary
    public SqlSessionTemplate NCSqlSessionTemplate() throws Exception {
        SqlSessionTemplate template = new SqlSessionTemplate(NCSqlSessionFactoryBean().getObject());
        return template;
    }

}
package com.siter.config;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;

@Configuration
//FC接口類的一些包名掃描
@MapperScan(basePackages = {"com.siter.mapper.FC"}, sqlSessionFactoryRef = "FCSqlSessionFactoryBean")
public class FcConfig {
    // 必須指定注入哪個數據源,否則找到多個會注入失敗
    @Autowired
    @Qualifier("FC")
    private DataSource db2;

    @Bean(name = "FCSqlSessionFactoryBean")
//    @Primary
    @ConfigurationProperties(prefix = "mybatis.fc") // 和 配置文件中的前綴保持一致
    // @Primary 如果SqlSessionFactoryBean的名字和MybatisDB2Config中的一致(默認方法名),需要加上這個註解,優先注入該SqlSessionFactoryBean
    // 這裏我們通過bean指定了name,並且方法名也不一樣,所以如果情況不一樣,看是否需要加入@Primary 。 如果需要兩個方法上加一個就行了,都加的話,spring又找不到bean注入啦。。
    public SqlSessionFactoryBean FCSqlSessionFactoryBean() throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        // 配置數據源
        sqlSessionFactoryBean.setDataSource(db2);
        // 如下的兩行代碼僅僅用於*.xml文件,如果整個持久層操作沒用到xml文件的話,比如使用註解的方式,則無需加
        // 解決配置到配置文件中通過*配置找不到mapper文件的問題。 如果不設置這一行,在配置文件中,只能使用數組的方式一個個的羅列出來,並且要指定具體的文件名
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/FC/*.xml"));
//      sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(" classpath:mapper/FC/FCBdMarbasclassMapper.xml"));

        // 也可以通過在application.yml中配置
        //sqlSessionFactoryBean.setTypeAliasesPackage("net.sitir.ergatemd2mq.entity.FC");
        return sqlSessionFactoryBean;
    }

    // 可選,如果需要通過SqlSessionTemplate來操作持久層就通過@Bean實例化
    @Bean(name = "FCSqlSessionTemplate")
//    @Primary
    public SqlSessionTemplate FCSqlSessionTemplate() throws Exception {
        SqlSessionTemplate template = new SqlSessionTemplate(FCSqlSessionFactoryBean().getObject());
        return template;
    }

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