在 MyBatis 中配置多个数据源可以通过以下几个步骤来实现。你需要在 Spring Boot 或者 Spring 配置中同时使用多个 DataSource 来配置多个数据库连接。以下是一些常见的做法:
一、配置多个 DataSource 数据源
首先,确保你有多个数据库的配置信息。你可以通过在 application.yml 或 application.properties 文件中配置多个数据源。
1.yml配置(常规)
(1)无主数据源配置
spring: datasource: # 数据源1 db1: driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql:///db1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone= GMT%2B8 username: root password: root type: com.alibaba.druid.pool.DruidDataSource # 数据源2 db2: driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql:///db2?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone= GMT%2B8 username: root password: 123456 type: com.alibaba.druid.pool.DruidDataSource #连接池 hikari: maximum-pool-size: 10 minimum-idle: 5 max-lifetime: 500000 connection-timeout: 30000 idle-timeout: 600000 |
(2)有主数据源配置
spring: datasource: dynamic: #默认主数据源 primary: db1 datasource: # 数据源1 db1: driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql:///db1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezon e=GMT%2B8 username: root password: root type: com.alibaba.druid.pool.DruidDataSource # 数据源2 db2: driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql:///db2?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezon e=GMT%2B8 username: root password: 123456 type: com.alibaba.druid.pool.DruidDataSource #连接池(如果使用 Druid 则此部分可以省略) hikari: maximum-pool-size: 10 minimum-idle: 5 max-lifetime: 500000 connection-timeout: 30000 idle-timeout: 600000 |
(3)有无主数据源的区别
主数据源是默认使用的数据源,当没有明确指定时,Spring 会使用它。
其他数据源需要显式配置和使用,通常通过 @Qualifier 注解来指定。
主数据源的事务管理器 通常是默认的事务管理器,除非你明确指定其他数据源的事务管理器。
二、mybatis配置
spring: # MyBatis mybatis: # Mapper XML 文件的路径 mapper-locations: classpath:mapper/*Mapper.xml # 实体类的路径(扫描相应包下的 POJO 类) type-aliases-package: com.example.main.test.po # 配置 MyBatis 配置文件路径 config-location: classpath:mybatis-config.xml # MyBatis 配置项 configuration: # 启用 MyBatis 二级缓存 cache-enabled: true # 配置日志输出级别(一般为 DEBUG) log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 默认情况下 MyBatis 会禁用驼峰命名转换,如果你希望启用,需要添加以下配置 map-underscore-to-camel-case: true # 设置全局的 SQL 执行超时时间(单位:秒) default-statement-timeout: 30 # 执行插入、更新、删除操作时,是否忽略插入时的字段为空值 jdbc-type-for-null: NULL # 开启自动映射 auto-mapping-behavior: FULL |
三、配置 DataSource 和 SqlSessionFactory
1.分散配置(推荐)
(1)数据源1配置
@Configuration @MapperScan(basePackages = "com.example.main.test.mapper.db1", sqlSessionFactoryRef = "db1SqlSessionFactory", sqlSessionTemplateRef = "db1SqlSessionTemplate") public class DataSource1Config { //数据源 //ConfigurationProperties绑定属性并读取配置 //primary表优先级 @Bean(name = "db1DataSource") @ConfigurationProperties(prefix = "spring.datasource.db1") //@Primary public DataSource dataSource() { return DataSourceBuilder.create().build(); } //数据会话工厂 @Bean(name = "db1SqlSessionFactory") //@Primary public SqlSessionFactory sqlSessionFactory(@Qualifier("db1DataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource()); bean.setMapperLocations(new PathMatchingResourcePatternResolver() .getResource("classpath:mapper/db1/*.xml")); return bean.getObject(); } //事务管理 @Bean(name = "db1TransactionManager") //@Primary public DataSourceTransactionManager dbTransactionManager(@Qualifier("db1DataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } //自动管理和事务控制 @Bean("db1SqlSessionTemplate") //@Primary public SqlSessionTemplate sqlSessionTemplate(@Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) { return new SqlSessionTemplate(sqlSessionFactory); } } |
(2)数据源2配置
@Configuration @MapperScan(basePackages = "com.example.main.test.mapper.db2", sqlSessionFactoryRef = "db2SqlSessionFactory", sqlSessionTemplateRef = "db2SqlSessionTemplate") public class DataSource1Config { //数据源 //ConfigurationProperties绑定属性并读取配置 @Bean(name = "db2DataSource") @ConfigurationProperties(prefix = "spring.datasource.db2") public DataSource dataSource() { return DataSourceBuilder.create().build(); } //数据会话工厂 @Bean(name = "db2SqlSessionFactory") public SqlSessionFactory sqlSessionFactory(@Qualifier("db2DataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource()); bean.setMapperLocations(new PathMatchingResourcePatternResolver() .getResource("classpath:mapper/db2/*.xml")); return bean.getObject(); } //事务管理 @Bean(name = "db2TransactionManager") public DataSourceTransactionManager dbTransactionManager(@Qualifier("db2DataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } //自动管理和事务控制 @Bean("db2SqlSessionTemplate") public SqlSessionTemplate sqlSessionTemplate(@Qualifier("db2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) { return new SqlSessionTemplate(sqlSessionFactory); } } |
(3)配置解析
注解:
@Configuration:表示这是一个配置类。
@MapperScan:扫描指定包下的MyBatis的Mapper接口,参数:
basePackages:指定包路径;
sqlSessionFactoryRef:指定SqlSessionFactory的名称;
sqlSessionTemplateRef:指定sqlSessionTemplateRef的名称。
@Bean:将方法返回值作为bean注册到Spring容器中。
@ConfigurationProperties:将yml配置文件中以spring.datasource.xxx为前缀的属性绑定到drivingTrainDataSource实例的属性上。
@Primary:表示优先级,即主数据源。
@Qualifier:指定使用的对象。
方法:
dataSource():创建数据源,注入到Spring容器中。
sqlSessionFactory():创建数据会话工厂,注入到Spring容器中。
dbTransactionManager():创建事务管理器,注入到Spring容器中。
platformTransactionManager():创建事务管理器,注入到Spring容器中。
sqlSessionTemplate():创建自动管理和事务控制,注入到Spring容器中。
2.聚合配置(不推荐)
聚合多个配置,统一管理。
@Configuration @MapperScan(basePackages = "com.example.main.test.mapper", sqlSessionFactoryRef = "db1sqlSessionFactory") public class DataSourceConfig { // 第一个数据源的配置(主数据源) @Primary @Bean(name = "db1DataSource") @ConfigurationProperties(prefix = "spring.datasource.db1") public DataSource dataSource1() { return DataSourceBuilder.create().build(); } // 第二个数据源的配置 @Bean(name = "db2DataSource") @ConfigurationProperties(prefix = "spring.datasource.db2") public DataSource dataSource2() { return DataSourceBuilder.create().build(); } // 其他配置...... } |
四、动态切换数据源、指定事务管理器
在某些场景下,可能需要动态切换数据源。可以通过 AOP 或 @Transactional 注解来实现。
此外,每个数据源有独立的事务管理器,因此需要在方法上使用 @Transactional 注解时,明确指定事务管理器。
@Transactional(transactionManager = "db1TransactionManager") public void someMethodForDataSource1() { // 使用 db1DataSource 进行操作 } @Transactional(transactionManager = "db2TransactionManager") public void someMethodForDataSource2() { // 使用 db2DataSource 进行操作 } |
五、总结
通过上面的方法,你可以在 MyBatis 中配置多个数据源,并分别为不同的数据库设置独立的 SqlSessionFactory 和 Mapper 扫描配置。这样,MyBatis 会为不同的数据源处理相应的 SQL 会话和事务管理。