天天看點

mybatis 多資料源_Spring Boot + Mybatis多資料源和動态資料源配置

應用場景

項目需要同時連接配接兩個不同的資料庫A, B,并且它們都為主從架構,一台寫庫,多台讀庫,

多資料源。

mybatis 多資料源_Spring Boot + Mybatis多資料源和動态資料源配置

首先要将spring boot自帶的DataSourceAutoConfiguration禁掉,因為它會讀取application.properties檔案的spring.datasource.*屬性并自動配置單資料源。在@SpringBootApplication注解中添加exclude屬性即可:

@SpringBootApplication(exclude = {

DataSourceAutoConfiguration.class

})

public class TitanWebApplication {

public static void main(String[] args) {

SpringApplication.run(TitanWebApplication.class, args);

}

}

然後在application.properties中配置多資料源連接配接資訊:

# titan庫

spring.datasource.titan-master.url=jdbc:mysql://X.X.X.X:port/titan?characterEncoding=UTF-8

spring.datasource.titan-master.username=

spring.datasource.titan-master.password=

spring.datasource.titan-master.driver-class-name=com.mysql.jdbc.Driver

# 連接配接池配置

# 省略

# 其它庫

spring.datasource.db2.url=jdbc:mysql://X.X.X.X:port/titan2?characterEncoding=UTF-8

spring.datasource.db2.username=

spring.datasource.db2.password=

spring.datasource.db2.driver-class-name=com.mysql.jdbc.Driver

由于我們禁掉了自動資料源配置,因些下一步就需要手動将這些資料源建立出來:

@Configuration

public class DataSourceConfig {

@Bean(name = "titanMasterDS")

@ConfigurationProperties(prefix = "spring.datasource.titan-master") // application.properteis中對應屬性的字首

public DataSource dataSource1() {

return DataSourceBuilder.create().build();

}

@Bean(name = "ds2")

@ConfigurationProperties(prefix = "spring.datasource.db2") // application.properteis中對應屬性的字首

public DataSource dataSource2() {

return DataSourceBuilder.create().build();

}

}

接下來需要配置兩個mybatis的SqlSessionFactory分别使用不同的資料源:

@Configuration

@MapperScan(basePackages = {"titan.mapper"}, sqlSessionFactoryRef = "sqlSessionFactory1")

public class MybatisDbAConfig {

@Autowired

@Qualifier("titanMasterDS")

private DataSource ds1;

@Bean

public SqlSessionFactory sqlSessionFactory1() throws Exception {

SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();

factoryBean.setDataSource(ds1); // 使用titan資料源, 連接配接titan庫

return factoryBean.getObject();

}

@Bean

public SqlSessionTemplate sqlSessionTemplate1() throws Exception {

SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory1()); // 使用上面配置的Factory

return template;

}

}

經過上面的配置後,titan.mapper下的Mapper接口,都會使用titan資料源。同理可配第二個SqlSessionFactory:

@Configuration

@MapperScan(basePackages = {"other.mapper"}, sqlSessionFactoryRef = "sqlSessionFactory2")

public class MybatisDbBConfig {

@Autowired

@Qualifier("ds2")

private DataSource ds2;

@Bean

public SqlSessionFactory sqlSessionFactory2() throws Exception {

SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();

factoryBean.setDataSource(ds2);

return factoryBean.getObject();

}

@Bean

public SqlSessionTemplate sqlSessionTemplate2() throws Exception {

SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory2());

return template;

}

}

完成這些配置後,假設有2個Mapper titan.mapper.UserMapper和other.mapper.RoleMapper,使用前者時會自動連接配接titan庫,後者連接配接ds2庫。

動态資料源

使用動态資料源的初衷,是能在應用層做到讀寫分離,即在程式代碼中控制不同的查詢方法去連接配接不同的庫。除了這種方法以外,資料庫中間件也是個不錯的選擇,它的優點是資料庫叢集對應用來說隻暴露為單庫,不需要切換資料源的代碼邏輯。

我們通過自定義注解 + AOP的方式實作資料源動态切換。

首先定義一個ContextHolder, 用于儲存目前線程使用的資料源名:

public class DataSourceContextHolder {

public static final Logger log = LoggerFactory.getLogger(DataSourceContextHolder.class);

public static final String DEFAULT_DS = "titan-master";

private static final ThreadLocal contextHolder = new ThreadLocal<>();

// 設定資料源名

public static void setDB(String dbType) {

log.debug("切換到{}資料源

繼續閱讀