原文地址:https://www.cnblogs.com/youzhibing/p/18019399
老项目的屎山代码一定不能乱改呀,改了就容易出现各种奇葩的问题。
有一句话说的好:屎山代码改好没绩效,改出问题要背锅,吃力不讨好,又不是不能跑!
今天分享一位新人将 MyBatis 替换成 MyBatis-Plus 后出了生产问题的案例。
MyBatis 替换成 MyBatis-Plus
背景介绍
一个老项目,数据库用的是 MySQL
5.7
.
36
, ORM 框架用的 MyBatis
3.5
.
0
, mysql-connector-java 版本是
5.1
.
26
新来了一个干练的小伙,精力充沛,看着就是一个喜欢折腾的主
他就觉得 MyBatis 使用起来不够简单,要写的代码还比较多,觉得有必要替换成 MyBatis-Plus
Mybatis-Plus 替换 Mybatis
先准备一张表 tbl_order ,然后初始化 2 条数据
为了简化演示,我就直接用 Mybatis-Plus 搭建一个示例 demo ,以此来模拟下 "小伙" 替换的过程
只是用 MyBatis-Plus 替换 MyBatis ,其他组件的版本暂不动
Mybatis-Plus 版本就用 "小伙" 引用的版本:
3.1
.
1
, mysql-connector-java 版本保持不变还是
5.1
.
26
示例代码:play_it_safe
此时运行
com.qsl.OrderTest#orderListAllTest
,会报错,异常信息如下
注意看 Caused by:
不支持的转换类型:
java.time.LocalDateTime
谁不支持?mysql-connector-java 不支持!
那 mysql-connector-java 哪个版本支持了,答案是:
5.1.37
升级 mysql-connector-java
将 mysql-connector-java 升级到 5.1.37 ,再执行下
com.qsl.OrderTest#orderListAllTest
不再报异常,查询结果也正确
MyBatis-Plus 替换 Mybatis 似乎就完成了
顺的让人有点怀疑
图片
Conversion not supported for type java.time.LocalDateTime
我们再回过头去看看前面说到的异常:Conversion not supported for type java.time.LocalDateTime
Mybatis-Plus 替换 MyBatis 之前没这个异常,替换之后就有了这个异常,这不是 Mybatis-Plus 的问题?
如何找这个异常的根因了?
很简单,直接从异常堆栈入手
点了之后,你会发现方法很简单
这么简单的代码能有什么问题?
大家注意看图中左上角 MyBatis 的版本,是
3.5.1
,并不是最初的 3.5.0
有小伙伴可能会问了:不是用 MyBatis-Plus 替换了 MyBatis 吗,怎么还有 Mybatis ?
这个问题问的真的好,我只想给你个大嘴巴子!
图片
你看下 MyBatis-Plus 的官方说明:
既然基于 Mybatis 3.5.0 没有抛异常,而基于 3.5.1 抛了异常,
LocalDateTimeTypeHandler
在 3.5.1 肯定做了调整
我们来看下调整了什么?
看出什么了?
MyBatis 3.5.0 会处理
LocalDateTime
类型的转换(将
java.sql.Timestamp
转换成
java.time.LocalDateTime
)
然而,注意了,然而来了!!!
然而从 MyBatis 3.5.1 开始,不再处理
LocalDateTime
(还包括:
LocalDate
、
LocalTime
)类型的转换
而是交由 JDBC 组件,也就是 mysql-connector-java 来实现
而巧的是, mysql-connector-java 5.1.26 不支持类型
LocalDateTime
。
图片
那它支持哪些类型了?
我们同样从异常堆栈入手
点了之后,可以看到下图
往上滑动鼠标,就可以看到支持的类型了
确实没有
LocalDateTime
、
LocalDate
和
LocalTime
mysql-connector-java 5.1.37 开始支持
LocalDateTime
、
LocalDate
和
LocalTime
,前面已经介绍过了,不再过多赘述
总结下异常根因:
MyBatis 3.5.1 开始不再处理 LocalDateTime 、 LocalDate 和 LocalTime 的转换,而 mysql-connector-java 5.1.37 之前都不支持这些类型