Mybatis切换数据源,切换数据源依据须从ThreadLocal里取值

一、自定义生成SqlSessionFactory
写一个类,在类的定义上加两个注解:
@Configuration
@EnableConfigurationProperties(MybatisPlusProperties.class)

类中添加以下方法,生成自定义SqlSessionFactory:
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        // 方法中,调用自定义的FactoryBean
         MybatisSqlSessionFactoryBeanRewrite factory = new MybatisSqlSessionFactoryBeanRewrite();
    }
二、重写MybatisSqlSessionFactoryBean为MybatisSqlSessionFactoryBeanRewrite
修改以下方法:
protected SqlSessionFactory buildSqlSessionFactory() throws Exception {
      // 修改生成SqlSessionFactory的方式,把MybatisSqlSessionFactoryBuilder修改为MybatisSqlSessionFactoryBuilderRewrite,其余不变。
      final SqlSessionFactory sqlSessionFactory = new MybatisSqlSessionFactoryBuilderRewrite().build(targetConfiguration);
}
三、重写MybatisSqlSessionFactoryBuilder为MybatisSqlSessionFactoryBuilderRewrite;重写SqlSessionFactoryBuilder为SqlSessionFactoryBuilderRewrite,修改SqlSessionFactoryBuilderRewrite的build方法:
    public SqlSessionFactory build(Configuration config) {
        return new DefaultSqlSessionFactoryRewrite(config);
    }
四、重写DefaultSqlSessionFactory为DefaultSqlSessionFactoryRewrite
修改openSessionFromDataSource方法:
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
 Transaction tx = null;
        try {
            final Environment environment = configuration.getEnvironment();
            final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
            log.info("切换数据源");
            Long userId = ThreadLocalUtil.get();
            SysTenant sysTenant = null;
            try (
                    Connection connection = environment.getDataSource().getConnection()
            ) {
                connection.setAutoCommit(true);
                Statement state = connection.createStatement();
                ResultSet resultSet = state.executeQuery("select * from sys_tenant where sys_tenant_id = " + userId);
                List<SysTenant> list = new ArrayList<SysTenant>();
                while(resultSet.next())
                {
                  Integer id = resultSet.getInt(1);
                    String tenantId = resultSet.getString(2);
                    String type = resultSet.getString(3);
                    String driverClassName = resultSet.getString(4);
                    String jdbcUrl = resultSet.getString(5);
                    String username = resultSet.getString(6);
                    String password = resultSet.getString(7);
                    String dataBase = resultSet.getString(8);

                    SysTenant sysTenantDatabase = new SysTenant();
                    sysTenantDatabase.setId(id);
                    sysTenantDatabase.setTenantId(tenantId);
                    sysTenantDatabase.setType(type);
                    sysTenantDatabase.setDriverClassName(driverClassName);
                    sysTenantDatabase.setJdbcUrl(jdbcUrl);
                    sysTenantDatabase.setUsername(username);
                    sysTenantDatabase.setPassword(password);
                    sysTenantDatabase.setDataBase(dataBase);
                    list.add(sysTenantDatabase);
                }
                if (list.size() <= NumberConstants.INT_ZERO) {
                    throw new RuntimeException("租户信息异常,请配置租户");
                }
                sysTenant = list.get(NumberConstants.INT_ZERO);
            } catch (SQLException e) {
                log.error("查询数据源失败", e);
            }
            DataSourceBuilder<?> dataSourceBuilder = DataSourceBuilder.create();
            dataSourceBuilder.driverClassName(sysTenant.getDriverClassName());
            dataSourceBuilder.url(sysTenant.getJdbcUrl());
            dataSourceBuilder.username(sysTenant.getUsername());
            dataSourceBuilder.password(sysTenant.getPassword());
            DataSource source = dataSourceBuilder.build();
            tx = transactionFactory.newTransaction(source, level, autoCommit);
            final Executor executor = configuration.newExecutor(tx, execType);
            return new DefaultSqlSession(configuration, executor, autoCommit);
        } catch (Exception e) {
            closeTransaction(tx);
            throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
        } finally {
            ErrorContext.instance().reset();
        }
    }
五、以上方法可以根据ThreadLocal中的值切换数据源,如果需要根据传入的参数切换数据源,修改DefaultSqlSession类中的方法,从入参parameter中,可取出参数值。

  • 23
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值