根据Mybatis-plus配置动态数据源-从数据库获取源
1.引入依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>${version}</version>
</dependency>
2.配置文件
spring:
## 数据库配置(支持动态多数据源)
datasource:
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false #设置严格模式,默认false不启动. 启动后在未匹配到指定数据源时候会抛出异常,不启动则使用默认数据源.
datasource:
master:
url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic
username: root
password: 123456
3.执行器重写
/**
* 参数数据源解析 @DS("#test")
*
* @author lt
* @date 2020-06-13
*/
public class TestDsProcessor extends DsProcessor {
private static final String TEST = "#test";
/**
* 抽象匹配条件 匹配才会走当前执行器否则走下一级执行器
*
* @param key DS注解里的内容
* @return 是否匹配
*/
@Override
public boolean matches(String key) {
return key.startsWith(TEST);
}
/**
* 抽象最终决定数据源
*
* @param invocation 方法执行信息
* @param key DS注解里的内容
* @return 数据源名称
*/
@Override
public String doDetermineDatasource(MethodInvocation invocation, String key) {
Object[] arguments = invocation.getArguments();
// 获取注解方法的连接名称(此处是把数据库ID当成连接名称)
String testDbId = String.valueOf(arguments[arguments.length - 1]);
// 验收数据源是否有效
TestManagerImpl testManager = (TestManagerImpl ) SpringFactoryUtil.getObject("testManagerImpl");
DataSource dbSource = testManager .getDbSource(testDbId);
if (dbSource != null) {
return datasourceName;
} else {
throw new RuntimeException("数据源" + datasourceName + "已断开!");
}
}
4.动态数据源配置
@Configuration
public class DynamicDataSourceConfiguration {
@Bean
public DsProcessor dsProcessor() {
TestDsProcessor testDsProcessor = newTestDsProcessor();
//设置多个执行器
//testDsProcessor.setNextProcessor(new Test2DsProcessor());
return testDsProcessor;
}
@Bean
public BaseTypeHandler customObjectTypeHandler() {
return new CustomObjectTypeHandler();
}
}
5.数据源连接
@Component
public class TestManagerImpl implements TestManager {
/**
* 从动态数据源中获取数据源
* @param dbName 数据源名称
* @return
*/
public DataSource getDbSource(String dbName) {
// 如果动态数据源不存在,则尝试从数据源重载
// 通过数据源名称获取数据源
DynamicRoutingDataSource dynamicRoutingDataSource = (DynamicRoutingDataSource) dataSource;
DataSource dynamicDataSource = dynamicRoutingDataSource.getDataSource(dbName);
if (dynamicDataSource != null && !dynamicDataSource.equals(dynamicRoutingDataSource.determineDataSource())) {
return dynamicDataSource;
}
// 通过ID获取库表数据
TestDb testDb = testDbDao.selectById(dbName);
// 检查是否可连接()
Boolean result = checkDataSource(testDb .getJdbcUrl(), testDb .getDbUser(), testDb .getDbPassword());
if (result) {
DataSourceProperty dataSourceProperty = new DataSourceProperty();
// 把数据资源库表ID当数据源名称
dataSourceProperty.setPoolName(testDb .getId());
dataSourceProperty.setUrl(testDb .getJdbcUrl());
dataSourceProperty.setUsername(testDb .getDbUser());
dataSourceProperty.setPassword(testDb .getDbPassword());
dataSourceProperty.setDriverClassName(convertDbDriverClassName(testDb .getJdbcUrl()));
DataSource dataSource = dataSourceCreator.createDataSource(dataSourceProperty);
dynamicRoutingDataSource.addDataSource(dataSourceProperty.getPoolName(), dataSource);
dynamicDataSource = dynamicRoutingDataSource.getDataSource(dbName);
}
if (dynamicDataSource != null && !dynamicDataSource.equals(dynamicRoutingDataSource.determineDataSource())) {
return dynamicDataSource;
}
return null;
}
/**
* 检验连接是否正常
* @param jdbcUrl jdbc url
* @param dbUser 用户名
* @param dbPassword 密码
* @return
*/
private Boolean checkDataSource(String jdbcUrl, String dbUser, String dbPassword) {
try {
DriverManager.getConnection(jdbcUrl, dbUser, dbPassword);
} catch (SQLException e) {
logger.error("数据源配置 {} , 获取链接失败", jdbcUrl, e);
return Boolean.FALSE;
}
return Boolean.TRUE;
}
}
实体类
public class TestDb{
/**
* id
*/
private String id;
/**
* 数据库名称
*/
private String dbName;
/**
* 数据库连接名称
*/
private String dbConnectionName;
/**
* 数据库类型
*/
private String dbType;
/**
* 主机名
*/
private String dbHost;
/**
* 数据库端口
*/
private Integer dbPort;
/**
* 数据库账号
*/
private String dbUser;
/**
* 数据库密码
*/
private String dbPassword;
/**
* 连接地址
*/
private String jdbcUrl;
/**
* 备注
*/
private String remark;
}
使用
/**
* 执行动态数据源的分页查询
* @param tableName 表名
* @param page 分页参数
* @param testDbId 表ID(也是数据源连接名)
* @return
*/
@Override
@DS("#test")
public Page executeTestDbTablePage(String tableName, Page page, String testDbId) {
}