本文章详细介绍了如何在Spring Boot项目中使用MyBatis实现多数据源以及动态切换数据源的方法和技巧。适合中级Java开发人员参考学习。
在开发企业级应用时,有时需要连接到多个数据库来满足不同的业务需求,比如主从数据库架构,以便实现读写分离,提高系统性能。Spring Boot 结合 Mybatis 的多数据源和动态数据源配置就是解决此类问题的有效手段。
首先,在项目中我们需要禁用 Spring Boot 默认的数据源配置。这可以通过在主配置类(通常带有 `@SpringBootApplication` 注解的类)中添加 `exclude = { DataSourceAutoConfiguration.class }` 来实现,这样就阻止了基于 application.properties 文件中的默认数据源创建:
```java
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class TitanWebApplication {
public static void main(String[] args) {
SpringApplication.run(TitanWebApplication.class, args);
}
}
```
接着,在 `application.properties` 文件中定义多个数据库的数据连接信息。例如,对于两个名为“titan”和“db2”的数据源:
```properties
# titan 数据源 (主库)
spring.datasource.titan-master.url=jdbc:mysql://X.X.X.X:port/titan?characterEncoding=UTF-8
spring.datasource.titan-master.username=your_username
spring.datasource.titan-master.password=your_password
spring.datasource.titan-master.driver-class-name=com.mysql.jdbc.Driver
# db2 数据源 (从库)
spring.datasource.db2.url=jdbc:mysql://X.X.X.X:port/titan2?characterEncoding=UTF-8
spring.datasource.db2.username=your_username
spring.datasource.db2.password=your_password
spring.datasource.db2.driver-class-name=com.mysql.jdbc.Driver
```
然后,我们创建两个 `@Bean` 方法来表示这两个数据源,并通过 `@ConfigurationProperties` 注解将配置文件中的属性绑定到这些 Bean 上:
```java
@Configuration
public class DataSourceConfig {
@Bean(name = titanMasterDS)
@ConfigurationProperties(prefix = spring.datasource.titan-master)
public DataSource dataSource1() {
return DataSourceBuilder.create().build();
}
@Bean(name = ds2)
@ConfigurationProperties(prefix = spring.datasource.db2)
public DataSource dataSource2() {
return DataSourceBuilder.create().build();
}
}
```
有了数据源后,我们需要为每个数据源创建对应的 Mybatis `SqlSessionFactory`。这样,Mybatis 就可以根据不同的数据源执行 SQL 语句:
```java
@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);
return factoryBean.getObject();
}
}
```
对于另一个数据源,同样创建一个配置类(如 `MybatisDbBConfig`),并配置对应的 `SqlSessionFactory`。使用 `@Qualifier(ds2)` 来注入第二个数据源。
在实际的应用场景中,可能还需要进行数据源的切换,即动态地选择不同的数据库连接来执行操作。这通常通过 AOP 实现,在其中定义一个方法根据业务逻辑或请求参数决定当前应使用的数据源。然后可以在需要的地方(如 Service 层的方法)调用这个方法来进行数据源的选择。
```java
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSourceKey();
}
}
使用 ThreadLocal 存储和获取当前的数据源 key:
public class DataSourceContextHolder {
private static final ThreadLocal contextHolder = new ThreadLocal<>();
public static void setDataSourceKey(String key) {
contextHolder.set(key);
}
public static String getDataSourceKey() {
return contextHolder.get();
}
public static void clearDataSourceKey() {
contextHolder.remove();
}
}
```
在 Service 层的方法中,根据业务需求设置数据源的 key:
```java
@Service
public class SomeService {
@Autowired
private DynamicDataSource dynamicDataSource;
public void someMethod() {
DataSourceContextHolder.setDataSourceKey(titanMasterDS);
// 执行相关操作
DataSourceContextHolder.setDataSourceKey(ds2);
// 执行相关操作
DataSourceContextHolder.clearDataSourceKey();
}
}
```
总结来说,Spring Boot 结合 Mybatis 的多数据源配置涉及禁用默认的数据源、定义多个数据库连接信息、创建对应的 `SqlSessionFactory` 和在需要时实现动态地选择不同的数据源。这样的配置能够灵活处理复杂的企业级应用中与多个数据库交互的场景,提高系统的可扩展性和灵活性。