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.mzph.cn/pingmian/69819.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MongoDB 基本操作

一、数据库操作 1. 切换或创建数据库 使用use命令切换到指定数据库,若该数据库不存在,在首次插入数据时会自动创建。 use myDatabase 2. 查看所有数据库 使用show dbs命令查看 MongoDB 实例中的所有数据库。 show dbs 3. 删除当前数据库 使用db.…

网络安全事件分级

对网络安全事件进行必要分级,是做好应急响应工作的前提。网络安全事件分级要统筹考虑诸多因素,直观展示信息安全事件的风险程度,为后续处置工作提供重要参考。 一、网络安全事件的分级要素 对网络安全事件的分级主要考虑3个要素&#xff1a…

三步本地部署deepseekr1,支持macOs,ubuntu,Windows

一、ollama安装: ollama官网:Ollama Ollama 是一款支持在 Windows、macOS 和 Linux 上本地运行大型语言模型的工具。以下是针对不同操作系统的安装指南: 1、Windows 系统 下载安装包:访问 Ollama 官方下载页面,选择适用于 Windows 的安装包进行下载。 运行安装程序:下…

前端开发中处理浮点数精度丢失问题的多种方法

1. 使用 toFixed() 方法 toFixed()是 JavaScript 内置的 Number 对象方法,它会根据指定的小数位数返回一个字符串。这个方法在输出时对结果进行了四舍五入,因此它并不总是能保证数学上的精确性,但它对于展示目的来说通常是足够的。 let num…

MySQL中类似PostgreSQL中的string_agg函数--GROUP_CONCAT函数的使用

文章目录 结论:MySQL没有string_agg,但有GROUP_CONCATGROUP_CONCAT函数的基本用法示例注意事项 系统变量 group_concat_max_len 如何查看和设置查看当前的group_concat_max_len值设置group_concat_max_len值 相关源码相关链接 结论:MySQL没有…

基于Django以及vue的电子商城系统设计与实现

基于Django以及vue的电子商城系统设计与实现 引言 随着电子商务的快速发展,越来越多的企业和个人选择搭建线上商城,以提供更加便捷的购物体验。本文基于Python开发了一套电子商城系统,后端采用Django框架,前端使用Vue.js&#x…

妙用Pytest内置request Fixture 监控测试执行过程

关注开源优测不迷路 大数据测试过程、策略及挑战 测试框架原理,构建成功的基石 在自动化测试工作之前,你应该知道的10条建议 在自动化测试中,重要的不是工具 你是否曾希望你的测试能根据命令行输入做出不同的行为? 也许是根据测试…

hbase快照同步到目标集群出现ERROR Multiple regions have the same startkey问题分析

问题现象 源集群表split/merge过程中创建快照,该快照同步到目标集群,目标集群恢复快照后,进行hbck检查,就会出现异常报错: ERROR Multiple regions have the same startkey; 问题分析 首先,出现上述问题可能有如下两种原因: 源集群中snapshot表本身就存在这种问题,没…

安科瑞光伏发电防逆流解决方案--守护电网安全,提升能源效率

在当今大力发展清洁能源的时代背景下,光伏发电作为一种可持续的能源解决方案, 正得到越来越广泛的应用。然而,光伏发电过程中出现的逆流问题,给电网的安全稳定 运行带来了诸多挑战。若不能有效解决,不仅可能影响电网…

用语言模型探索语音风格空间:无需情感标签的情 感TTS

用语言模型探索语音风格空间:无需情感标签的情感TTS 原文:Exploring speech style spaces with language models: Emotional TTS without emotion labels 今天我们要说的是 一种无需情感标签的情感TTS。提出了一个基于FastSpeech2的E-TTS框架&#xff0…

HTML之JavaScript运算符

HTML之JavaScript运算符 1.算术运算符 - * / %除以0,结果为Infinity取余数,如果除数为0,结果为NaN NAN:Not A Number2.复合赋值运算符 - * / %/ 除以0,结果为Infinity% 如果除数为0,结果为NaN NaN:No…

.net处理dynamic类型运行之后的数据

在 .NET 中,dynamic 类型用于在运行时处理对象,它可以绕过编译时的类型检查,让你在运行时动态地访问对象的成员。当处理 dynamic 类型的 List 数据时,你可以按照以下步骤进行操作。 ### 示例场景 假设你有一个 dynamic 类型的 Li…

Linux网络编程--Udp套接字+实战 (万字详解,超详细!!)

目录 套接字协议: 协议(protocol): 创建套接字(Create Socket): 绑定服务器地址 开始通信 Udp服务器设计--V1 Udp服务器设计--V2 引入进程池 待更新 套接字协议: 协议(protocol): 如果2个距离很远的人想要进行交流&#xff…

<tauri><rust><GUI>使用tauri创建一个图片浏览器(文件夹遍历、图片切换)

前言 本文是基于rust和tauri,由于tauri是前、后端结合的GUI框架,既可以直接生成包含前端代码的文件,也可以在已有的前端项目上集成tauri框架,将前端页面化为桌面GUI。 环境配置 系统:windows 10平台:visual studio code语言:rust、javascript库:tauri2.0概述 本文是…

C# 两种方案实现调用 DeepSeek API

目录 序 开发运行环境 访问API的一个通用方法 原生官网实现 申请 API key 调用实现 调用示例 腾讯云知识引擎原子调用 申请 API key 调用示例 小结 序 DeepSeek(深度求索) 最近可谓火爆的一塌糊涂,具体的介绍这里不再赘述&#x…

Flutter PIP 插件 ---- Android

在 Flutter Android 应用中实现画中画功能 画中画(Picture-in-Picture, PiP)模式允许您的应用在一个固定在屏幕角落的小窗口中运行,同时用户可以与其他应用进行交互。本指南将介绍如何在 Flutter Android 应用中实现画中画功能,包括其局限性和解决方案。 项目地址 flutter_p…

中间件-安装Minio-集成使用(ubantu-docker)

目录 1、安装docer 2、运行以下命令拉取MinIO的Docker镜像 3、检查当前所有Docker下载的镜像 4、创建目录 5、创建Minio容器并运行 6、SDK操作 FileUploader.java 1、安装docer 参考这篇:Linux安装Docker 2、运行以下命令拉取MinIO的Docker镜像 docker pull…

【CXX】0 Rust与C 互操作利器:CXX库介绍与示例

CXX库是一个非常强大的工具,它使得Rust和C之间的互操作性变得既安全又高效。本专栏将展示如何使用CXX库来桥接Rust和C代码,同时保持两者语言的特性和惯用法。 一、关键概念回顾 类型安全:CXX库通过静态分析类型和函数签名来保护Rust和C的不…

LabVIEW用户界面设计原则

在LabVIEW开发中,用户界面(UI)设计不仅仅是为了美观,它直接关系到用户的操作效率和体验。一个直观、简洁、易于使用的界面能够大大提升软件的可用性,尤其是在复杂的实验或工业应用中。设计良好的UI能够减少操作错误&am…

使用 Docker 安装 Open WebUI 并集成 Ollama 的 DeepSeek 模型

文章目录 使用 Docker 安装 Open WebUI 并集成 Ollama 的 DeepSeek 模型前提条件1. 安装ollama2. 拉取deepseek的模型3. Open-WebUI 说明4. 启动容器文档的方法如下优化命令(可选)1. 增加了健康检查机制(--health-cmd)2. 使 WebUI…