欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > Spring Boot 配置 Mybatis 读写分离

Spring Boot 配置 Mybatis 读写分离

2025/2/13 15:40:31 来源:https://blog.csdn.net/xiaoyao888/article/details/145573988  浏览:    关键词:Spring Boot 配置 Mybatis 读写分离

JPA 的读写分离配置不能应用在 Mybatis 上, 所以 Mybatis 要单独处理

为了不影响原有代码, 使用了增加拦截器的方式, 在拦截器里根据 SQL 的 CRUD 来路由到不同的数据源

需要单独增加Mybatis的配置

@Configuration
public class MyBatisConfig {@Beanpublic SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();sessionFactory.setDataSource(dataSource);// 注册插件sessionFactory.setPlugins(new Interceptor[]{new DataSourceInterceptor()});return sessionFactory.getObject();}
}

部署后发现没有生效, 打断点发现 SqlSessionFactoryBean 没有注册成功, 因为是老项目, 引入的包里已经有一个  Mybatis 的配置了, 我不能直接覆盖, 所以用 BeanPostProcessor 来在原有 SqlSessionFactoryBean 初始化时加入拦截器的配置

@Configuration
public class MyBatisConfig {@Bean@ConditionalOnBean(name="routingDataSource")public BeanPostProcessor sqlSessionFactoryBeanPostProcessor(@Qualifier("routingDataSource") DataSource routingDataSource) {return new BeanPostProcessor() {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof SqlSessionFactory) {SqlSessionFactory SqlSessionFactory = (SqlSessionFactory) bean;try {SqlSessionFactory.getConfiguration().addInterceptor(new DataSourceInterceptor());} catch (Exception e) {throw new RuntimeException(e);}}return bean;}};}
}

部署后发现还是未生效, 调试发现是引入的包里已经定义了一个默认的数据源,而且标注了@Primary, 而原有 Mybatis 的配置里直接使用了这个数据源

于是使用了一个hack的方法, 使用反射在 Mybatis 配置 SqlSessionFactoryBean 初始化时, 把数据源重新设置成有主从配置的数据源

@Configuration
public class MyBatisConfig {@Bean@ConditionalOnBean(name="routingDataSource")public BeanPostProcessor sqlSessionFactoryBeanPostProcessor(@Qualifier("routingDataSource") DataSource routingDataSource) {return new BeanPostProcessor() {
@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof SqlSessionFactory) {try {SqlSessionFactory sqlSessionFactory = (SqlSessionFactory) bean;org.apache.ibatis.session.Configuration configuration = sqlSessionFactory.getConfiguration();// 使用反射或其他方式修改配置中的数据源Field dataSourceField = configuration.getEnvironment().getClass().getDeclaredField("dataSource");dataSourceField.setAccessible(true);dataSourceField.set(configuration.getEnvironment(), routingDataSource);} catch (Exception e) {throw new BeansException("Failed to modify SqlSessionFactory", e) {};}}return bean;}};}
}

再次部署测试通过

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com