R2dbc Mybatis 整合

R2dbc Mybatis 整合

涉及到框架
  • r2dbc-spi
  • r2dbc-pool
  • reactor-core
  • mybatis
  • mybatis-dynamic-sql
  • spring-r2dbc
背景原因
  • 在介入Reactive技术栈时,将原有的mybatis框架 reactive 化的过程中,整合Transaction遇到的技术难点
  • 考察过社区很多 reactive 应用框架,除了Spring-R2DBC外,大部分事物处理,和connection管理,都还停留在阻塞式处理的思路中。并没有真正的实现reactive化
技术难点
  • 1 . 由于Reactive的编程模式相对于传统编程模式的变化,ThreadLocal已无法在reactive环境中使用,造成connection无法缓存,导致在业务流程上挂载事务处理时,无法缓存connection
  • 2 . 虽然r2dbc的connection提供了transaction操作,但要将mybatis框架 reactive 化的过程中,通过Context合理的缓存Connection不太好实现
背景知识
Reactive-Mybatis
  • 在整合r2dbcmybatis时,有一系列问题需要适配:

    • reactive项目中无法使用ThreadLocal,需要替换为Context,用于缓存Connection
    • reactive,属于数据流处理的形式,原有Mybatis中的处理逻辑是Blocking操作,需要替换为No-Blocking
    • 保留原有参数绑定和结果解析方案,并适配到reactive流处理过程中
    • r2dbc-spi驱动中,PreparedStatement中的占位符,不同驱动有不同的实现,而JDBC统一使用?为占位符,由驱动翻译占位符,这里需要转换为框架适配,否则适配不同的r2dbc驱动
    • 由于reactive本身就有cache性质,需要将mybatis中的cache剥离掉
    • 适配 r2dbc Data-Type,否则数据映射不成功
  • 在整合r2dbc事物时,需要使用动态代理来实现缓存ConnectionContext中,并保证,在一个事物中,Connection是同一个,这样才能实现Transaction
  • 在解析返回结果集时,需要切换思路,由于数据是按照数据流的形式返回的,那么在合并和解析结果集时,需要合理缓存已解析的数据,从而可以保留原有mybatis的一对多映射功能
  • 在适配SelectKey功能时,需要将原有的beforeafter操作,转移到executor中操作,原有的SelectKey功能是阻塞的,需要将流程贯穿到整个executor过程中,才能保留beforeafter操作
  • 由于r2dbc的限制,要么只返回自生成自增主键,要么返回影响行数
Reactive-Mybatis-Spring
  • 整合到Spring的过程中,需要将Executor挂在到Spring的事物管理器上,并交由Spring管理
  • Spring通过ConnectionFactoryUtils.currentConnectionFactory(connectionFactory)来判断,当前Context是否有事物管理
  • Spring提供了TransactionAwareConnectionFactoryProxy来代理事物,需要将ReactiveSqlSession中使用的ConnectionFactory替换为TransactionAwareConnectionFactoryProxy才能和Spring的事物管理器一起使用
相关信息
  • 已通过Mybatis源码,适配了R2DBC,保留Mybatis原用功能,尽可能的保证项目顺利迁移。具体支持的功能,请移步 reactive-mybatis-support
  • 已发布到中央仓库,测试了MySQL / PostgreSQL/H2/Mssql/Oracle
相关源码维护在GitHub,欢迎Issue和Star reactive-mybatis-support

Java技术整理
整理,总结Java后端技术相关资料
96 声望
12 粉丝
0 条评论
推荐阅读
刨根问底 Redis, 面试过程真好使
充满寒气的互联网如何在面试中脱颖而出,平时积累很重要,八股文更不能少!下面带来的这篇 Redis 问答希望能够在你的 offer 上增添一把🔥。

菜农曰17阅读 879

封面图
与RabbitMQ有关的一些知识
工作中用过一段时间的Kafka,不过主要还是RabbitMQ用的多一些。今天主要来讲讲与RabbitMQ相关的一些知识。一些基本概念,以及实际使用场景及一些注意事项。

lpe2348阅读 1.8k

封面图
万字详解,吃透 MongoDB!
MongoDB 是一个基于 分布式文件存储 的开源 NoSQL 数据库系统,由 C++ 编写的。MongoDB 提供了 面向文档 的存储方式,操作起来比较简单和容易,支持“无模式”的数据建模,可以存储比较复杂的数据类型,是一款非常...

JavaGuide4阅读 377

封面图
Git操作不规范,战友提刀来相见!
年终奖都没了,还要扣我绩效,门都没有,哈哈。这波骚Git操作我也是第一次用,担心闪了腰,所以不仅做了备份,也做了笔记,分享给大家。问题描述小A和我在同时开发一个功能模块,他在优化之前的代码逻辑,我在开...

王中阳Go5阅读 2.1k评论 2

封面图
Redis 发布订阅模式:原理拆解并实现一个消息队列
“65 哥,如果你交了个漂亮小姐姐做女朋友,你会通过什么方式将这个消息广而告之给你的微信好友?““那不得拍点女朋友的美照 + 亲密照弄一个九宫格图文消息在朋友圈发布大肆宣传,暴击单身狗。”像这种 65 哥通过朋...

码哥字节6阅读 1.3k

封面图
PHP转Go实践:xjson解析神器「开源工具集」
我和劲仔都是PHP转Go,身边越来越多做PHP的朋友也逐渐在用Go进行重构,重构过程中,会发现php的json解析操作(系列化与反序列化)是真的香,弱类型语言的各种隐式类型转换,很大程度的减低了程序的复杂度。

王中阳Go6阅读 1.4k评论 2

封面图
NB的Github项目,看到最后一个我惊呆了!
最近看到不少好玩的、实用的 Github 项目,就来给大家推荐一把。中国制霸生成器最近在朋友圈非常火的一个小网站,可以在线标记 居住、短居、游玩、出差、路过 标记后可生成图片进行社区分享,标记过的信息会记录...

艾小仙5阅读 1.6k评论 1

96 声望
12 粉丝
宣传栏