根据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) {
}
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值