当前位置: 首页 > news >正文

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;}};}
}

再次部署测试通过


http://www.mrgr.cn/news/90407.html

相关文章:

  • jenkins备份还原配置文件
  • 基于STM32的智能鱼缸水质净化系统设计
  • C++引用深度详解
  • Flutter_学习记录_基本组件的使用记录_2
  • 数据结构与算法-单链表
  • UnrealEngine开发无人机飞行模拟软件的手柄如何选择
  • 伺服使能的含义解析
  • ubuntu20.04+ROS+Gazebo+px4+QGC+MAVROS
  • Packer 手动修复安装腾讯云插件
  • unity 安装Entities
  • 深入理解Java对接DeepSeek
  • 【Python深入浅出㉗】Python3正则表达式:开启高效字符串处理大门
  • 数据结构与算法之排序算法-快速排序(分治)
  • Linux内核实时机制x - 实时性之中断响应优化
  • 1.【线性代数】——方程组的几何解释
  • DeepSeek投喂数据(训练AI)
  • 如何评估云原生GenAI应用开发中的安全风险(下)
  • 解锁设计模式:代理模式的多面解析与实战
  • 计算机毕业设计——Springboot的社区维修平台旅游管理
  • Python查询成交量