-----------------------------------------------------------------------------------------------------------
在 Spring Boot 中使用 MyBatis 连接多数据源,通常可以通过配置多个数据源实例并绑定不同的 Mapper 路径来实现。以下是详细步骤:
1. 准备依赖
在
pom.xml 中添加必要依赖(以 MySQL 为例):xml
<!-- Spring Boot 核心 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><!-- MyBatis 整合 Spring Boot -->
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.0</version>
</dependency><!-- MySQL 驱动 -->
<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope>
</dependency><!-- 数据源配置(可选,Spring Boot 2.0+ 自带 HikariCP) -->
<dependency><groupId>com.zaxxer</groupId><artifactId>HikariCP</artifactId>
</dependency>
2. 配置多数据源信息
在
application.yml 中配置多个数据源的连接信息(以两个数据源为例):yaml
spring:datasource:# 主数据源(primary)primary:jdbc-url: jdbc:mysql://localhost:3306/db1?useSSL=false&serverTimezone=UTCusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver# 第二个数据源(secondary)secondary:jdbc-url: jdbc:mysql://localhost:3306/db2?useSSL=false&serverTimezone=UTCusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver# MyBatis 配置(可选,如 mapper 位置、别名等)
mybatis:type-aliases-package: com.example.entity # 实体类包路径configuration:map-underscore-to-camel-case: true # 下划线转驼峰
3. 配置数据源实例
创建配置类,分别实例化两个数据源,并指定主数据源(
@Primary)。主数据源配置(PrimaryDataSourceConfig)
java
运行
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
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.core.io.support.PathMatchingResourcePatternResolver;import javax.sql.DataSource;@Configuration
// 扫描主数据源对应的 Mapper 接口,并指定 SqlSessionFactory
@MapperScan(basePackages = "com.example.mapper.primary", // 主数据源的 Mapper 路径sqlSessionFactoryRef = "primarySqlSessionFactory"
)
public class PrimaryDataSourceConfig {// 实例化主数据源@Primary@Bean(name = "primaryDataSource")@ConfigurationProperties(prefix = "spring.datasource.primary") // 绑定配置前缀public DataSource primaryDataSource() {return DataSourceBuilder.create().build();}// 主数据源的 SqlSessionFactory@Primary@Bean(name = "primarySqlSessionFactory")public SqlSessionFactoryBean primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();sessionFactory.setDataSource(dataSource);// 指定主数据源的 Mapper XML 路径(如果有)sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/primary/*.xml") // 例如:resources/mybatis/primary/);return sessionFactory;}
}
第二个数据源配置(SecondaryDataSourceConfig)
java
运行
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
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.core.io.support.PathMatchingResourcePatternResolver;import javax.sql.DataSource;@Configuration
// 扫描第二个数据源对应的 Mapper 接口
@MapperScan(basePackages = "com.example.mapper.secondary", // 第二个数据源的 Mapper 路径sqlSessionFactoryRef = "secondarySqlSessionFactory"
)
public class SecondaryDataSourceConfig {// 实例化第二个数据源@Bean(name = "secondaryDataSource")@ConfigurationProperties(prefix = "spring.datasource.secondary")public DataSource secondaryDataSource() {return DataSourceBuilder.create().build();}// 第二个数据源的 SqlSessionFactory@Bean(name = "secondarySqlSessionFactory")public SqlSessionFactoryBean secondarySqlSessionFactory(@Qualifier("secondaryDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();sessionFactory.setDataSource(dataSource);// 指定第二个数据源的 Mapper XML 路径sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/secondary/*.xml") // 例如:resources/mybatis/secondary/);return sessionFactory;}
}
4. 编写 Mapper 和实体类
- 主数据源的 Mapper 接口放在
com.example.mapper.primary包下,对应的 XML 文件放在resources/mybatis/primary/下。 - 第二个数据源的 Mapper 接口放在
com.example.mapper.secondary包下,对应的 XML 文件放在resources/mybatis/secondary/下。
示例(主数据源 Mapper):
java
运行
// com.example.mapper.primary.UserMapper.java
public interface UserMapper {User getById(Long id);
}
对应的 XML:
xml
<!-- resources/mybatis/primary/UserMapper.xml -->
<mapper namespace="com.example.mapper.primary.UserMapper"><select id="getById" resultType="com.example.entity.User">select * from user where id = #{id}</select>
</mapper>
5. 使用数据源
在 Service 中直接注入对应的 Mapper 即可自动使用绑定的数据源:
java
运行
@Service
public class UserService {@Autowiredprivate UserMapper userMapper; // 自动关联主数据源@Autowiredprivate OrderMapper orderMapper; // 自动关联第二个数据源(假设 OrderMapper 在 secondary 包下)public User getUser(Long id) {return userMapper.getById(id); // 查询 db1}public Order getOrder(Long id) {return orderMapper.getById(id); // 查询 db2}
}
关键说明
- @Primary 注解:必须指定一个主数据源,否则 Spring 会因无法确定默认数据源而报错。
- Mapper 路径隔离:通过
@MapperScan的basePackages区分不同数据源的 Mapper,避免冲突。 - 事务管理:如果需要事务,需为每个数据源配置
DataSourceTransactionManager,并在 Service 中通过@Transactional(value = "事务管理器名称")指定。
例如,为主数据源添加事务管理器:
java
运行
@Primary
@Bean(name = "primaryTransactionManager")
public DataSourceTransactionManager primaryTransactionManager(@Qualifier("primaryDataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);
}
使用时:
java
运行
@Transactional(value = "primaryTransactionManager")
public void saveUser(User user) {userMapper.insert(user);
}
通过以上步骤,即可实现 Spring Boot + MyBatis 多数据源的配置和使用。如果需要更多数据源,按相同逻辑添加配置类即可。
-----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------