MyBatis执行SQL时如何获取对应的数据源?
实现方案
MyBatis Interceptor 可以通过以下两种常用方式获取对应执行SQL的DataSource,适配不同的业务场景:
- 单数据源/固定SqlSessionFactory场景
初始化SqlSessionFactory时将DataSource绑定到MyBatis全局Configuration属性中,拦截器中直接从调用链路获取即可:
初始化阶段代码:
拦截器中获取代码:SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); factoryBean.setDataSource(yourDataSource); org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration(); // 将DataSource存入Configuration的自定义属性中 configuration.getVariables().put("useDataSource", yourDataSource); factoryBean.setConfiguration(configuration); // 其余SqlSessionFactory初始化逻辑@Override public Object intercept(Invocation invocation) throws Throwable { // 从Invocation参数第一个位置拿到MappedStatement MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; DataSource dataSource = (DataSource) mappedStatement.getConfiguration() .getVariables().get("useDataSource"); // 此处已拿到对应DataSource,可继续处理SQL捕获逻辑 return invocation.proceed(); } - 多数据源动态切换场景
若项目使用了动态数据源实现(例如Spring的AbstractRoutingDataSource、MyBatis-Plus动态数据源插件),可直接在拦截器中获取当前线程路由的实际数据源:@Override public Object intercept(Invocation invocation) throws Throwable { // 从Spring上下文获取动态数据源实例 AbstractRoutingDataSource dynamicDataSource = ApplicationContextUtil.getBean(AbstractRoutingDataSource.class); // 获取当前线程绑定的数据源标识 Object lookupKey = dynamicDataSource.determineCurrentLookupKey(); // 路由获取实际执行的DataSource DataSource currentDataSource = dynamicDataSource.getResolvedDataSources().get(lookupKey); // 后续业务逻辑 return invocation.proceed(); }
若你的项目为简单单数据源场景,也可直接从Spring上下文获取DataSource Bean,MyBatis实际执行使用的数据源和Spring容器中注册的为同一实例。
内容的提问来源于stack exchange,提问作者Yuxuan Sun
相关产品推荐
相关产品推荐

