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日

相关文章

  • Redis+Hbase+RocketMQ 实际使用问题案例分享

    需求 将Hbase数据,解析后推送到RocketMQ。 redis使用list数据类型,存储了需要推送的数据的RowKey及表名。 简单画个流程图就是: 分析及确定方案 Redis 明确list中元素结构{“rowkey”:rowkey,”table”:table}解析出rowkey; 一次取多个元素加快效率; 取了之后放入重试队列,并删除原来的元素; 处理…

    Redis 2023年4月11日
    00
  • Mysql Row_Format 参数讲解

    今天更改数据引擎的时候,突然出现了 Table storage engine for ‘#sql-3e9_132’ doesn’t have this option 这样的提示: 通过搜索,发现了一些端倪,下面是对于Row_Format参数的讲解: 在MYSQL中, 若一张表里面不存在varchar、text以及其变形、blob以及其变形的字段的话,那么张这…

    MySQL 2023年4月16日
    00
  • Redis批量删除KEY的方法

    Redis 中有删除单个 Key 的指令 DEL,但好像没有批量删除 Key 的指令,不过我们可以借助 Linux 的 xargs 指令来完成这个动作。   代码如下: redis-cli keys “*” | xargs redis-cli del //如果redis-cli没有设置成系统变量,需要指定redis-cli的完整路径 //如:/opt/red…

    Redis 2023年4月13日
    00
  • PHP源码之 ext/mysql扩展部分

    为了更好地说明“PHP源码之 ext/mysql扩展部分”的攻略,下面我将按照如下顺序进行讲解: 简介 ext/mysql扩展 安装PHP及扩展 源码结构分析 函数及其使用示例 简介 ext/mysql扩展 ext/mysql扩展是一个用于支持mysql数据库的PHP扩展,它已经在PHP 5.5.0版本中移除,并在PHP 7.0中被官方废弃。 安装PHP及扩…

    database 2023年5月21日
    00
  • ubuntu 安装openssh服务器的教程详解

    下面为您详细讲解“ubuntu 安装openssh服务器的教程详解”。 一、安装openssh服务器 在ubuntu系统中,首先需要安装openssh服务器软件,具体操作如下: 打开终端,输入以下命令: sudo apt-get update sudo apt-get install openssh-server 第一条命令表示更新软件包列表; 第二条命令表…

    database 2023年5月22日
    00
  • dedecms负载性能优化实例,三招让你的dedecms快10倍以上

    前言 dedecms是一个非常流行的开源内容管理系统,因为其使用简单、功能强大、可扩展性强,成为众多网站建设者的首选。然而,随着网站不断的增长,过量的访问可能会导致dedecms运行缓慢甚至崩溃。因此,在网站性能优化方面,需要采取一些有效的方法使dedecms具有更好的负载性能,提高网站的稳定性和运行速度。 本篇攻略将介绍三种dedecms性能优化方法,这些…

    database 2023年5月19日
    00
  • MySQL修改和删除触发器(DROP TRIGGER)方法详解

    MySQL修改触发器的方法 使用命令SHOW TRIGGERS命令获取已经存在的触发器信息,确定要修改的触发器的名称。例如: SHOW TRIGGERS FROM database_name; 使用ALTER TRIGGER命令更新触发器。例如: ALTER TRIGGER trigger_name ON table_name [AFTER|BEFORE] …

    MySQL 2023年3月10日
    00
  • CentOS 8安装ZABBIX4.4的指南

    以下是详细讲解“CentOS 8安装ZABBIX4.4的指南”的完整攻略。 1. 前置条件 在开始安装ZABBIX之前,您需要满足以下前提条件: 在CentOS 8操作系统上具有sudo权限的访问。 已经配置并启用了EPEL存储库。 2. 安装MariaDB ZABBIX需要使用数据库存储其数据。在本教程中,我们将使用MariaDB,它是一个免费的且开源的关…

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