Mybatis中时间类型筛选查询报错_invalid comparison_ java.time.LocalDateTime and java.lang.String

博客主要讲述联调时使用LocalDateTime类型时间筛选数据报错问题。入参包含日期字符串,报错显示不能对LocalDateTime和String进行比较。经分析,这是MyBatis 3.3.*版本问题,该版本时间不能与空字符串比较。解决办法是移除startLastTime!=''的判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

联调时发现通过LocalDateTime类型时间进行筛选数据时,报错
java.lang.IllegalArgumentException: invalid comparison: java.time.LocalDateTime and java.lang.String

一、问题

入参:{size: 10, current: 1, startDate: “2023-09-18”, endDate: “2023-09-19”}
报错:java.lang.IllegalArgumentException: invalid comparison: java.time.LocalDateTime and java.lang.String

在这里插入图片描述

二、代码

接收dto:


private LocalDateTime startLastTime;


private LocalDateTime endLastTime;


private String channelId;


private LocalDateTime lastTime;


private Integer online;

private Integer isDelete;

sql语句:

<select id="queryPage"
  resultType="com.*.DetailsDTO"
  parameterType="com.*.CommonDTO">
  SELECT
  device.*,
  base.*,
  info.*
  FROM
  base_info AS base
  LEFT JOIN device_info AS device ON device.id = base.device_id
  LEFT JOIN status_info AS info ON base.id = info.machine_id
  <where>
    <if test="startLastTime != null and  startLastTime !='' ">
      <![CDATA[ and base.last_time >= #{startLastTime}]]>
    </if>
    <if test="endLastTime != null and endLastTime !=''">
      <![CDATA[ and base.last_time <= #{endLastTime}]]>
    </if>
    <if test="channelId != null and channelId !='' ">
      and base.channel_id = #{channelId}
    </if>
    <if test="isDelete != null and isDelete !=''">
      and base.is_delete = #{isDelete}
    </if>
    <if test="online != null and online == 1 ">
      <![CDATA[ and info.last_time >= #{lastTime}]]>
    </if>
      <if test="online != null and online == 0 ">
      <![CDATA[ and info.last_time < #{lastTime}]]>
    </if>
    </where>
    </select>

三、分析问题

问题点:

<if test="startLastTime != null and  startLastTime !='' ">
  <![CDATA[ and base.last_time >= #{startLastTime}]]>
</if>
<if test="endLastTime != null and endLastTime !=''">
  <![CDATA[ and base.last_time <= #{endLastTime}]]>
</if>

这个错误是由于mybatis版本问题导致,这个版本中时间不能与空字符串进行比较。3.3.*版本应该都会有这个问题。把LocalDateTime类型和string类型进行比较,就会出现这个错误这里的startLastTime是LocalDateTime类型的在进行if判断的时候和 ‘’ 空字符串进行比较,这里就会报这个错误。

四、解决问题

只需要把startLastTime!= ‘’ 移除就可以了

<if test="startLastTime != null ">
  <![CDATA[ and base.last_time >= #{startLastTime}]]>
</if>
<if test="endLastTime != null ">
  <![CDATA[ and base.last_time <= #{endLastTime}]]>
</if>
<think>好的,我现在需要帮助用户解决MyBatis中出现的“invalid comparison: java.util.Date and java.lang.String”错误。用户提到想通过使用to_char函数来修改这个问题。我需要先理解这个错误的原因,然后找到正确的解决方法。 首先,根据用户提供的引用内容,这个错误通常是因为在MyBatis的XML映射文件中,将Date类型的字段与空字符串进行了比较,例如`createTime != ''`。在MyBatis 3.3.0及以上版本中,这样的比较会导致类型不匹配的错误,因为Date和String类型不能直接比较。 接下来,用户想使用to_char函数来解决这个问题。我需要回忆一下在MyBatis中如何处理日期转换。通常,数据库如Oracle支持to_char函数将日期转换为字符串,但MySQL使用的是date_format函数。不过,用户的问题可能与数据库类型无关,更多是MyBatis自身的处理机制。 正确的做法应该是避免将Date类型的参数与空字符串比较。根据引用[3]和[4],解决方案是移除对空字符串的判断,只保留非空判断。例如,将`<if test="createTime != null and createTime != ''">`改为`<if test="createTime != null">`。此外,如果确实需要格式化日期,可以在SQL中使用数据库的函数,比如在MySQL中使用date_format,或者在Oracle中使用to_char,但需要确保传入的参数是String类型,或者在XML中正确使用类型转换。 用户提到使用to_char,可能是指将数据库中的日期字段转换为字符串进行比较,这样可以避免类型冲突。例如,在Oracle中可以这样写:`to_char(create_time, 'YYYY-MM-DD') = #{createTimeStr}`,其中createTimeStr是用户传入的字符串参数。同时,在Java代码中确保传入的参数是字符串格式,或者在MyBatis中处理参数类型。 另外,检查MyBatis的版本也很重要,因为引用[3]提到3.3.0版本存在这个bug,升级到更高版本可能已经修复,或者需要调整代码逻辑。 总结步骤:1. 移除Date类型与空字符串的比较;2. 使用数据库函数转换日期格式;3. 确保传入参数类型正确;4. 调整MyBatis版本或配置。</think>### MyBatis日期比较错误的解决方法 当MyBatis中出现`invalid comparison: java.util.Date and java.lang.String`错误时,通常是因为在XML映射文件中将`java.util.Date`类型与空字符串`''`进行了直接比较。以下是具体修改方法和注意事项: --- #### 错误原因分析 1. **类型不匹配**:在条件判断中(如`<if test="createTime != null and createTime != ''">`),`createTime`是`Date`类型,而`''`是字符串类型,直接比较会触发类型检查异常[^3][^4]。 2. **MyBatis版本问题**:该问题在MyBatis 3.3.0中尤为常见,因框架对类型校验更严格[^3]。 --- #### 修改方法 ##### 1. 移除对空字符串的无效判断 直接删除`createTime != ''`的条件,仅保留非空判断: ```xml <if test="createTime != null"> AND DATE(create_time) = DATE(#{createTime}) </if> ``` ##### 2. 使用数据库函数格式化日期(如需要字符串比较) 若必须将日期字段转为字符串格式进行比较,需根据数据库类型选择函数: - **Oracle**:使用`to_char` ```xml <if test="createTimeStr != null and createTimeStr != ''"> AND to_char(create_time, 'YYYY-MM-DD') = #{createTimeStr} </if> ``` - **MySQL**:使用`date_format` ```xml <if test="createTimeStr != null and createTimeStr != ''"> AND date_format(create_time, '%Y-%m-%d') = #{createTimeStr} </if> ``` 此时需确保传入参数`createTimeStr`为字符串类型(如前端传递格式化的日期字符串)。 ##### 3. 参数类型处理 在Java代码中,若需传递格式化后的字符串参数: ```java // 示例:将Date转为字符串 String createTimeStr = new SimpleDateFormat("yyyy-MM-dd").format(createTime); paramMap.put("createTimeStr", createTimeStr); ``` --- #### 注意事项 1. **避免混合类型比较**:不要同时判断`Date`类型是否为`null`和是否等于空字符串[^2][^4]。 2. **参数传递一致性**:若使用字符串比较,确保参数类型与SQL中的格式化结果一致。 3. **版本兼容性**:升级MyBatis至3.3.1+版本可部分缓解此问题,但核心解决仍需代码调整[^3]。 --- #### 示例修正对比 **错误代码**: ```xml <if test="startTime != null and startTime != ''"> AND create_time >= #{startTime} </if> ``` **正确代码**: ```xml <if test="startTime != null"> AND create_time >= #{startTime} </if> ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

后端马农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值