MyBatis-Plus多数据源支持,40. MyBatis-Plus如何处理多数据源配置?如何实现动态切换数据源?
通过研究MyBatis-Plus官网
多数据源支持
dynamic-datasource 是一个开源的 Spring Boot 多数据源启动器,提供了丰富的功能,包括数据源分组、敏感信息加密、独立初始化表结构等。
使用方法:
-
引入依赖
-
<!--多个数据源-->
-
<dependency>
-
<groupId>com.baomidou</groupId>
-
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
-
<version>3.2.0</version>
-
</dependency>
-
<dependency>
-
<groupId>com.baomidou</groupId>
-
<artifactId>mybatis-plus-boot-starter</artifactId>
-
<version>3.2.0</version>
-
</dependency>
注意:项目中已经存在的mybatis的依赖需要注释,防止下面的共同存在的mybatis-spring产生冲突
-
配置数据源:如
-
spring.datasource.dynamic.primary=db1
-
spring.datasource.dynamic.strict=false
-
spring.datasource.dynamic.datasource.db1.url=jdbc:mysql://localhost:3306/ican?characterEncoding=utf-8&useUnicode=true&serverTimezone=UTC&allowMultiQueries=true
-
spring.datasource.dynamic.datasource.db1.username=root
-
spring.datasource.dynamic.datasource.db1.password=123456
-
spring.datasource.dynamic.datasource.db1.driver-class-name=com.mysql.cj.jdbc.Driver
-
-
spring.datasource.dynamic.datasource.db2.url=jdbc:mysql://192.168.21.37:3306/210_bm_inventory?useUnicode=true&allowPublicKeyRetrieval=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true
-
spring.datasource.dynamic.datasource.db2.username=root
-
spring.datasource.dynamic.datasource.db2.password=root123
-
spring.datasource.dynamic.datasource.db2.driver-class-name=com.mysql.cj.jdbc.Driver
一共配置了两个数据源 db1和db2 其中spring.datasource.dynamic.primary=db1配置主数据源为db1(没有注解时默认为主数据源)
spring.datasource.dynamic.strict=false 这个设置的是严格模式,true为开启,false为关闭。
开启@DS(db3) db3并不存在会直接报错,不开启则会采用主数据源进行二次尝试
-
使用
@DS切换数据源:
-
-
-
public interface InventoryDao {
-
-
-
List<Inventory> select(InventoryQuery query);
-
Integer insert(Inventory inventory);
-
Integer insertBatch(List<Inventory> inventorys);
-
Integer update(Integer id, int optionQty, int version,String lastUpdateBy);
-
Integer delete(Integer id);
-
}
类或者方法上都能加注释,注释括号里可以为组名(也就是2里面配置的db1,db2)也可以为具体某个库的名称。
目前主要用于wms仓储系统直接操作北猫商城里的inventory表。

如果引入不了依赖选择删除maven库中的具体文件夹或者依赖冲突可以选择直接删除总的maven库,或者解决冲突:进入pom

红线的就是有冲突的包

可以根据手动删除依赖、在Plugins下载Maven Helper插件进行解决、或者配置冲突子类不启动
在使用MyBatis-Plus的Spring Boot项目中,处理多数据源和动态切换数据源的需求常见于企业级应用中。下面详细介绍如何配置多数据源以及如何实现动态切换数据源。
1. 配置多数据源
1.1 在application.yml中配置多个数据源
首先,在Spring Boot的application.yml中配置多个数据源。
-
spring:
-
datasource:
-
db1:
-
url: jdbc:mysql://localhost:3306/db1
-
username: root
-
password: password
-
driver-class-name: com.mysql.cj.jdbc.Driver
-
db2:
-
url: jdbc:mysql://localhost:3306/db2
-
username: root
-
password: password
-
driver-class-name: com.mysql.cj.jdbc.Driver
1.2 定义数据源配置类
定义数据源配置类,配置不同的数据源和MyBatis的SqlSessionFactory。
-
-
public class DataSourceConfig {
-
-
-
-
-
public DataSource db1DataSource() {
-
return DataSourceBuilder.create().build();
-
}
-
-
-
-
public DataSource db2DataSource() {
-
return DataSourceBuilder.create().build();
-
}
-
-
-
-
public SqlSessionFactory db1SqlSessionFactory( DataSource dataSource) throws Exception {
-
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
-
sessionFactory.setDataSource(dataSource);
-
return sessionFactory.getObject();
-
}
-
-
-
public SqlSessionFactory db2SqlSessionFactory( DataSource dataSource) throws Exception {
-
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
-
sessionFactory.setDataSource(dataSource);
-
return sessionFactory.getObject();
-
}
-
-
-
-
public SqlSessionTemplate db1SqlSessionTemplate( SqlSessionFactory sqlSessionFactory) {
-
return new SqlSessionTemplate(sqlSessionFactory);
-
}
-
-
-
public SqlSessionTemplate db2SqlSessionTemplate( SqlSessionFactory sqlSessionFactory) {
-
return new SqlSessionTemplate(sqlSessionFactory);
-
}
-
}
1.3 配置Mapper扫描路径
使用@MapperScan注解指定不同数据源的Mapper接口所在的包路径。
-
-
-
public class Db1MyBatisConfig {
-
}
-
-
-
-
public class Db2MyBatisConfig {
-
}
2. 实现动态切换数据源
2.1 定义动态数据源类
通过继承AbstractRoutingDataSource实现动态数据源的切换。
-
public class DynamicDataSource extends AbstractRoutingDataSource {
-
-
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
-
-
public static void setDataSource(String dataSourceKey) {
-
contextHolder.set(dataSourceKey);
-
}
-
-
public static String getDataSource() {
-
return contextHolder.get();
-
}
-
-
public static void clearDataSource() {
-
contextHolder.remove();
-
}
-
-
-
protected Object determineCurrentLookupKey() {
-
return getDataSource();
-
}
-
}
2.2 配置动态数据源
在配置类中将多个数据源注册到DynamicDataSource,并设置默认数据源。
-
-
public class DynamicDataSourceConfig {
-
-
-
public DataSource dynamicDataSource( DataSource db1DataSource,
-
DataSource db2DataSource) {
-
Map<Object, Object> targetDataSources = new HashMap<>();
-
targetDataSources.put("db1", db1DataSource);
-
targetDataSources.put("db2", db2DataSource);
-
-
DynamicDataSource dynamicDataSource = new DynamicDataSource();
-
dynamicDataSource.setTargetDataSources(targetDataSources);
-
dynamicDataSource.setDefaultTargetDataSource(db1DataSource);
-
return dynamicDataSource;
-
}
-
-
-
public SqlSessionFactory sqlSessionFactory( DataSource dynamicDataSource) throws Exception {
-
SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
-
sessionFactoryBean.setDataSource(dynamicDataSource);
-
return sessionFactoryBean.getObject();
-
}
-
-
-
public SqlSessionTemplate sqlSessionTemplate( SqlSessionFactory sqlSessionFactory) {
-
return new SqlSessionTemplate(sqlSessionFactory);
-
}
-
}
2.3 动态切换数据源
在需要切换数据源的Service方法中,使用DynamicDataSource.setDataSource()来指定当前线程的数据源。
-
-
public class UserService {
-
-
-
private UserMapper userMapper;
-
-
-
private OrderMapper orderMapper;
-
-
public User getUserFromDb1(Integer id) {
-
DynamicDataSource.setDataSource("db1");
-
try {
-
return userMapper.findUserById(id);
-
} finally {
-
DynamicDataSource.clearDataSource();
-
}
-
}
-
-
public Order getOrderFromDb2(Integer id) {
-
DynamicDataSource.setDataSource("db2");
-
try {
-
return orderMapper.findOrderById(id);
-
} finally {
-
DynamicDataSource.clearDataSource();
-
}
-
}
-
}
3. 使用注解实现数据源切换
为了简化数据源切换的操作,可以使用自定义注解来切换数据源。
3.1 创建自定义注解
-
-
-
-
public DataSource {
-
String value() default "db1";
-
}
3.2 实现AOP切面
使用AOP切面拦截带有@DataSource注解的方法,动态切换数据源。
-
-
-
public class DynamicDataSourceAspect {
-
-
-
public void changeDataSource(JoinPoint point, DataSource dataSource) {
-
DynamicDataSource.setDataSource(dataSource.value());
-
}
-
-
-
public void clearDataSource(JoinPoint point, DataSource dataSource) {
-
DynamicDataSource.clearDataSource();
-
}
-
}
3.3 使用自定义注解
现在可以在Service层方法上使用@DataSource注解来动态切换数据源。
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@Autowired
private OrderMapper orderMapper;
@DataSource("db1")
public User getUserFromDb1(Integer id) {
return userMapper.findUserById(id);
}
@DataSource("db2")
public Order getOrderFromDb2(Integer id) {
return orderMapper.findOrderById(id);
}
}
4. 总结
MyBatis-Plus在Spring Boot项目中支持多数据源操作,并通过配置多个数据源和动态数据源实现动态切换数据源:
-
多数据源配置:通过配置多个
DataSource、SqlSessionFactory、SqlSessionTemplate来支持多数据源操作,不同包下的Mapper接口使用不同的数据源。 -
动态切换数据源:通过实现
AbstractRoutingDataSource和AOP切面,可以在运行时动态切换数据源,适用于复杂业务场景。 -
注解实现数据源切换:通过自定义注解和AOP结合,简化了数据源的动态切换操作,使代码更加简洁和易于维护。
通过这些配置,MyBatis-Plus可以轻松地支持多数据库的操作,并在需要时动态地切换数据源。
36. MyBatis如何支持多数据库操作?如何配置不同的数据源?
在许多企业级应用中,可能需要访问多个数据库。MyBatis 可以通过配置多个数据源和动态切换数据源来支持多数据库操作。下面介绍如何在 MyBatis 中配置和使用多个数据源。
1. 多数据源的基本配置
1.1 配置多个数据源
要支持多个数据源,首先需要在 Spring 或 Spring Boot 中配置不同的数据源。假设我们要连接两个数据库 db1 和 db2,可以通过以下步骤进行配置。
Spring Boot 示例:
-
application.yml配置文件:
-
spring:
-
datasource:
-
db1:
-
url: jdbc:mysql://localhost:3306/db1
-
username: root
-
password: password
-
driver-class-name: com.mysql.cj.jdbc.Driver
-
db2:
-
url: jdbc:mysql://localhost:3306/db2
-
username: root
-
password: password
-
driver-class-name: com.mysql.cj.jdbc.Driver
-
定义数据源配置类:
-
-
public class DataSourceConfig {
-
-
-
-
-
public DataSource db1DataSource() {
-
return DataSourceBuilder.create().build();
-
}
-
-
-
-
public DataSource db2DataSource() {
-
return DataSourceBuilder.create().build();
-
}
-
}
-
定义 SqlSessionFactory 和 SqlSessionTemplate:
-
-
-
public class Db1MyBatisConfig {
-
-
-
public SqlSessionFactory sqlSessionFactory( DataSource dataSource) throws Exception {
-
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
-
sessionFactory.setDataSource(dataSource);
-
return sessionFactory.getObject();
-
}
-
-
-
public SqlSessionTemplate sqlSessionTemplate( SqlSessionFactory sqlSessionFactory) {
-
return new SqlSessionTemplate(sqlSessionFactory);
-
}
-
}
-
-
-
-
public class Db2MyBatisConfig {
-
-
-
public SqlSessionFactory sqlSessionFactory( DataSource dataSource) throws Exception {
-
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
-
sessionFactory.setDataSource(dataSource);
-
return sessionFactory.getObject();
-
}
-
-
-
public SqlSessionTemplate sqlSessionTemplate( SqlSessionFactory sqlSessionFactory) {
-
return new SqlSessionTemplate(sqlSessionFactory);
-
}
-
}
1.2 使用不同数据源的 Mapper
通过以上配置,不同包下的 Mapper 将使用不同的数据源。假设 UserMapper 使用 db1,OrderMapper 使用 db2。
-
-
public interface UserMapper {
-
// 使用 db1 数据源
-
User findUserById(Integer id);
-
}
-
-
-
public interface OrderMapper {
-
// 使用 db2 数据源
-
Order findOrderById(Integer id);
-
}
2. 动态切换数据源
有时我们需要在运行时动态地切换数据源,比如在同一个 Service 中操作不同的数据源。可以通过 Spring 的 AbstractRoutingDataSource 实现动态切换。
2.1 定义动态数据源
-
public class DynamicDataSource extends AbstractRoutingDataSource {
-
-
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
-
-
public static void setDataSource(String dataSourceKey) {
-
contextHolder.set(dataSourceKey);
-
}
-
-
public static String getDataSource() {
-
return contextHolder.get();
-
}
-
-
public static void clearDataSource() {
-
contextHolder.remove();
-
}
-
-
-
protected Object determineCurrentLookupKey() {
-
return getDataSource();
-
}
-
}
2.2 配置数据源和 SqlSessionFactory
-
-
public class DynamicDataSourceConfig {
-
-
-
-
public DataSource dataSource( DataSource db1DataSource,
-
DataSource db2DataSource) {
-
Map<Object, Object> targetDataSources = new HashMap<>();
-
targetDataSources.put("db1", db1DataSource);
-
targetDataSources.put("db2", db2DataSource);
-
-
DynamicDataSource dynamicDataSource = new DynamicDataSource();
-
dynamicDataSource.setTargetDataSources(targetDataSources);
-
dynamicDataSource.setDefaultTargetDataSource(db1DataSource);
-
return dynamicDataSource;
-
}
-
-
-
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
-
SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
-
sessionFactoryBean.setDataSource(dataSource);
-
return sessionFactoryBean.getObject();
-
}
-
-
-
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
-
return new SqlSessionTemplate(sqlSessionFactory);
-
}
-
}
2.3 在 Service 中动态切换数据源
-
-
public class UserService {
-
-
-
private UserMapper userMapper;
-
-
-
private OrderMapper orderMapper;
-
-
public User getUserFromDb1(Integer id) {
-
DynamicDataSource.setDataSource("db1");
-
try {
-
return userMapper.findUserById(id);
-
} finally {
-
DynamicDataSource.clearDataSource();
-
}
-
}
-
-
public Order getOrderFromDb2(Integer id) {
-
DynamicDataSource.setDataSource("db2");
-
try {
-
return orderMapper.findOrderById(id);
-
} finally {
-
DynamicDataSource.clearDataSource();
-
}
-
}
-
}
3. 总结
MyBatis 支持通过配置多个数据源和动态切换数据源来实现多数据库操作:
-
多数据源静态配置:通过在 Spring 配置中定义多个
DataSource、SqlSessionFactory和SqlSessionTemplate来实现静态多数据源支持。不同包下的 Mapper 自动使用指定的数据源。 -
动态数据源切换:通过实现
AbstractRoutingDataSource动态数据源切换机制,能够在运行时动态地选择不同的数据源,这对于需要在同一事务中切换不同数据库操作的场景特别有用。
通过这些方法,MyBatis 可以灵活地支持多数据库操作,以满足复杂的业务需求。

浙公网安备 33010602011771号