背景
最近有一个数据统计服务需要升级SpringBoot的版本,由1.5.x.RELEASE直接升级到2.3.0.RELEASE,考虑到没有用到SpringBoot的内建SPI,升级过程算是顺利。但是出于代码洁癖和版本洁癖,看到项目中依赖的MyBatis的版本是3.4.5,相比当时的最新版本3.5.5大有落后,于是顺便把它升级到3.5.5。升级完毕之后,执行所有现存的集成测试,发现有部分OffsetDateTime类型入参的查询方法出现异常,于是进行源码层面的DEBUG找到最终的问题并且解决。
问题复现
项目中有一个查询方法类似下面的演示例子:
public interface OrderMapper { List selectByCreateTime(@Param("startCreateTime") OffsetDateTime startCreateTime, @Param("endCreateTime") OffsetDateTime endCreateTime);
对应的XML文件中的SQL代码段如下:
SELECT * FROM t_order WHERE deleted = 0 AND create_time =]]> #{startCreateTime} AND create_time #{e ndCreateTime}
上面的OrderMapper#selectByCreateTime()方法在MyBatis版本为3.4.5的前提下执行没有任何异常,当MyBatis版本升级为3.5.5后再次执行,在SQL执行日志输出正确的前提下返回了一个空集合,具体的内容如下:
查询订单列表:[]
虽然上帝视角是确认了入参解析有问题,但是基于第一次发生异常的日志,其实定位不到具体发生问题的位置,当时条件反射认为有几处地方会出现这类异常(SQL比较简单,可以排除人为写错SQL占位符的情况):
- MyBatis解析OffsetDateTime类型方法参数的方法有版本兼容问题。
- MySQL驱动包解析OffsetDateTime类型的参数有版本兼容问题。
- 前面两种情况混合相互影响导致的,其实这里也可以理解为同一种情况,因为MyBatis归根到