MyBatis版本升级导致OffsetDateTime入参解析异常问题复盘

下面是详细的攻略:

问题描述

在进行 MyBatis 版本升级时,发现项目中的 OffsetDateTime 类型的参数无法正常解析,导致调用 SQL 语句失败。

复盘过程

经过分析,我们发现问题出在 MyBatis 版本升级之后,其内部使用的 Jackson 依赖库(用于 JSON 数据的解析和序列化操作)也进行了更新,从 2.9.4 更新到了 2.11.3。其中,2.11.3 版本对于 OffsetDateTime 的解析策略做了一些改变,导致了参数解析异常。

具体来说,2.11.3 版本的解析策略是将参数按照 UTC(协调世界时)解析为一个时间戳,然后再根据时差转换成本地时间。但是,原先的版本则是直接按照本地时间解析参数。

如果我们直接使用 Mybatis 的默认配置,则会发生参数解析异常。要解决该问题,需要进行如下配置:

<!-- mybatis-config.xml 配置中增加如下配置 -->
<typeHandler>
    <jdbcType>OTHER</jdbcType>
    <javaType>java.time.OffsetDateTime</javaType>
    <handler>org.apache.ibatis.type.OffsetDateTimeTypeHandler</handler>
</typeHandler>

示例

我们提供两个示例,第一个示例展示了使用默认配置时的参数解析异常,第二个示例展示了使用了手动配置解析器之后的正常结果。

示例一

在 MyBatis 配置文件中增加如下配置:

<!-- mybatis-config.xml 中增加以下配置 -->
<settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

假设我们有以下的表结构:

CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `created_at` datetime(6) DEFAULT CURRENT_TIMESTAMP(6),
  `updated_at` datetime(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

然后我们想要使用 Mybatis 进行查询,查询用户创建时间在某一时间之后的数据。

public interface UserMapper {
    List<User> selectByCreatedAtAfter(@Param("createdAt") OffsetDateTime createdAt);
}
<!-- user.xml 中定义的 SQL -->
<select id="selectByCreatedAtAfter" resultType="User">
    SELECT *
    FROM `user`
    WHERE `created_at` > #{createdAt}
</select>
// 测试代码,模拟调用 Mapper 接口
public void testSelectByCreatedAtAfter() {
    OffsetDateTime createdAt = OffsetDateTime.of(LocalDateTime.of(2021, 8, 1, 0, 0, 0), ZoneOffset.UTC);
    List<User> users = userMapper.selectByCreatedAtAfter(createdAt);
    System.out.println(users);
}

运行该测试方法,会发现 Mybatis 解析参数时,无法将 OffsetDateTime 类型的参数正确解析为本地时间,从而查询失败,报错信息如下:

org.springframework.dao.DataIntegrityViolationException: 
### Error querying database.  Cause: java.sql.SQLException: 
### Cannot parse value of "java.time.OffsetDateTime" to java.sql.Timestamp

示例二

在 Mybatis 配置文件中增加以下配置:

<!-- mybatis-config.xml 配置 -->
<typeHandlers>
    <typeHandler javaType="java.time.OffsetDateTime" handler="org.apache.ibatis.type.OffsetDateTimeTypeHandler"/>
</typeHandlers>

然后重新执行上述的测试代码,此时参数解析正常,查询结果也正确输出。

总结

通过以上的分析和解决方案,我们可以得到以下几个结论:

  1. MyBatis 升级版本时,需要注意其所依赖的外部包,比如 Jackson。
  2. 当参数类型为 OffsetDateTime 时,需要针对这个类型单独配置 TypeHandler。
  3. 配置 TypeHandler 时,需要明确设置 jdbcType 和 javaType 两个属性。
  4. TypeHandler 的配置位置有多种,可以在 MyBatis 配置文件中全局配置,也可以针对单个字段或参数进行配置。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:MyBatis版本升级导致OffsetDateTime入参解析异常问题复盘 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • 搭建zabbix监控以及邮件报警的超级详细教学

    下面是关于搭建zabbix监控以及邮件报警的超级详细教学: 简介 Zabbix是一款开源的企业级监控系统,支持多种操作系统、数据源和应用程序的监控。我们可以利用Zabbix来监控服务器的各项参数,实现日常运维和故障排查。 Zabbix监控系统的报警方式有多种,其中包括邮箱报警、短信报警、微信报警等。本文将介绍基于邮箱报警的Zabbix监控系统搭建和配置。 环…

    database 2023年5月22日
    00
  • NodeJs Express框架操作MongoDB数据库执行方法讲解

    Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,非常适合编写高效的、可伸缩性的网络应用程序。Express.js是一个流行的轻量级web应用程序框架,可以快速而方便地构建复杂的Web应用程序。MongoDB是一种NoSQL数据库,经常与Node.js同时使用。 本文将介绍如何使用Node.js和Express.js来连…

    database 2023年5月18日
    00
  • Redis之哈希(hashes)类型命令

    Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。 Redis 中每个 hash 可以存储 232 – 1 键值对(40多亿)。 使用场景 : 用户信息     hset : 新建一个哈希表,设置成功返回1,如果已存在覆盖旧值,返回0(值可以为””) 127.0.0.1:6379> hset …

    Redis 2023年4月13日
    00
  • 详解如何在阿里云服务器安装Mysql数据库

    下面是详解如何在阿里云服务器安装Mysql数据库的完整攻略。 准备工作 在开始安装Mysql数据库之前,需要在阿里云服务器上安装好以下工具: yum:可以通过yum命令方便地安装软件包。 wget:可以通过wget命令下载Mysql安装包。 tar:可以通过tar命令解压Mysql安装包。 gcc、gcc-c++、make:这些工具是编译安装Mysql所必须…

    database 2023年5月22日
    00
  • 查看postgresql系统信息的常用命令操作

    下面是查看 PostgreSQL 系统信息的常用命令操作的完整攻略。 pg_controldata pg_controldata 命令用于查看 PostgreSQL 数据库集群控制文件的信息,包括该文件的位置、该集群的持久性实现方式和数据校验方式等。 使用示例: $ pg_controldata /path/to/postgresql/data 其中 /pa…

    database 2023年5月22日
    00
  • tp5.1 框架数据库常见操作详解【添加、删除、更新、查询】

    下面是 “tp5.1 框架数据库常见操作详解【添加、删除、更新、查询】” 的完整攻略: 1. 连接数据库 在使用数据库之前,需要先在应用配置文件中进行数据库的相关配置。具体操作如下: 打开 application 目录下的 config 目录; 打开 database.php 文件; 修改相应的数据库连接信息,例如: return [ // 数据库类型 ‘t…

    database 2023年5月22日
    00
  • scrapy-redis使用以及剖析

    scrapy-redis是一个基于redis的scrapy组件,通过它可以快速实现简单分布式爬虫程序,该组件本质上提供了三大功能: scheduler – 调度器 dupefilter – URL去重规则(被调度器使用) pipeline   – 数据持久化 scrapy-redis组件 1. URL去重 定义去重规则(被调度器调用并应用) a. 内部会使用…

    Redis 2023年4月12日
    00
  • Mysql的基础使用之MariaDB安装方法详解

    Mysql的基础使用之MariaDB安装方法详解 简介 MariaDB是MySQL的一个分支,即它是由MySQL的创始人创建的,作为MySQL的一个开源替代品。它是一个开放源代码、关系型数据库管理系统,可以很好的处理大量数据。在Linux操作系统中,MariaDB已经成为默认的数据库软件之一,很多应用都依赖于它。 MariaDB的安装方法 1.使用apt-g…

    database 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部