[MyBatis] MyBatis中对java.util.Date向数据库的java.sql.Timestamp转化

本文介绍了一个简单的Java示例,展示了如何将Date类型转换为Timestamp类型,并打印出具体的时间格式。

MyBatis对此,会自动转化

以下是Java代码手动转化

  Date d = new Date();
  System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(d));
  Timestamp ts = new Timestamp(d.getTime()); //Date to Timestamp
  System.out.println(ts.toString());

2018-04-20 15:25:25.638
2018-04-20 15:25:25.638

<think>我们正在处理MyBatis中出现的"invalid comparison: java.util.Date and java.lang.String"错误。根据引用内容,该错误通常发生在MyBatis的动态SQL中,当我们尝试将一个java.util.Date类型的属性与一个空字符串('')进行比较时。例如,在<if>标签中使用了`startTime != ''`这样的条件,而`startTime`是一个Date类型。 错误原因: 在MyBatis 3.3.0及以上版本中,OGNL表达式在进行比较时,如果遇到Date类型和String类型的比较(比如`startTime != ''`),会抛出该异常。因为Date类型和String类型不能直接比较。 解决方案: 根据引用[2]和引用[4],我们应该避免将Date类型与空字符串进行比较。只需要检查该属性是否为null即可,而不应该检查是否为空字符串。 错误示例: ```xml <if test="startTime != null and startTime != ''"> AND sorttime >= #{startTime} </if> ``` 正确写法: 去掉与空字符串的比较,只检查非null。 ```xml <if test="startTime != null"> AND sorttime >= #{startTime} </if> ``` 另外,引用[1]也提到,正确的写法是避免Date类型和空字符串的比较。 因此,总结解决方案如下: 1.MyBatis的动态SQL中,对于Date类型的参数,不要使用`!= ''`或`== ''`这样的判断。 2. 只使用`!= null`或`== null`来判断参数是否传递。 注意事项: 如果使用了低版本的MyBatis(比如3.2.8),可能不会出现这个错误,但升级到3.3.0及以上版本就会出现。因此,为了兼容性和代码健壮性,建议按照上述方案修改。 完整示例: 假设我们有一个查询,根据开始时间和结束时间过滤记录。修改前的错误写法可能导致异常,修改后只检查非null。 修改前: ```xml <select id="selectByTime" resultType="YourResultType"> SELECT * FROM table WHERE 1=1 <if test="startTime != null and startTime != ''"> AND sorttime >= #{startTime} </if> <if test="endTime != null and endTime != ''"> AND sorttime <= #{endTime} </if> </select> ``` 修改后: ```xml <select id="selectByTime" resultType="YourResultType"> SELECT * FROM table WHERE 1=1 <if test="startTime != null"> AND sorttime >= #{startTime} </if> <if test="endTime != null"> AND sorttime <= #{endTime} </if> </select> ``` 这样修改后,就不会再出现"invalid comparison: java.util.Date and java.lang.String"错误了。 另外,如果参数可能来自前端表单,有时会传递空字符串,那么建议在Java代码中将空字符串转换为null,或者在MyBatis的XML中使用更复杂的OGNL表达式来避免(但这样又会回到问题本身)。所以,最佳实践是在Java服务层处理好参数,避免将空字符串传递给MyBatisDate类型参数。 如果必须同时检查null和空字符串(比如参数是String类型,但需要转换Date类型比较),那么应该分情况处理: 1. 如果参数是String类型(例如前端传递的字符串,需要转换为日期),那么可以在动态SQL中先判断字符串不为null且不为空,然后再进行转换。但是,在MyBatis中,我们通常不会在动态SQL里做转换,而是在Java转换好再传入。 2. 如果参数是String类型,并且你确实需要在MyBatis中处理,那么可以这样写(注意:此时参数是String类型,所以可以比较字符串): ```xml <if test="startTime != null and startTime != ''"> AND sorttime >= #{startTime, jdbcType=TIMESTAMP} </if> ``` 但是,请注意,这里`startTime`是String类型,MyBatis会通过类型处理器将其转换数据库的日期类型。然而,这种方式要求传入的字符串格式必须能被数据库解析,否则会出错。所以,通常建议在Java层将字符串转换Date类型再传入。 总结:对于Date类型的参数,在MyBatis动态SQL中只做非null检查,避免检查空字符串。 引用说明:根据引用[1][2][3][4]的内容,该错误的确是由于Date和String比较导致,解决方法是去掉与空字符串的比较[^2][^4]。 相关问题: 1. MyBatis动态SQL中如何正确判断字符串类型参数的非空? 2. MyBatis中处理日期类型参数时需要注意哪些问题? 3. 如何避免MyBatis动态SQL中的类型不匹配错误? </think>### MyBatis中解决"invalid comparison: java.util.Date and java.lang.String"错误 在MyBatis中使用日期类型参数时,如果在动态SQL中错误地将`java.util.Date`与空字符串`''`进行比较,就会触发此异常。错误本质是**类型不匹配**:不能将日期对象与字符串直接比较。 #### 🚫 错误示例分析 ```xml <select id="findRecords" resultType="Record"> SELECT * FROM table WHERE 1=1 <!-- 错误写法:Date类型 vs 空字符串 --> <if test="startTime != null and startTime != ''"> AND create_time >= #{startTime} </if> </select> ``` 这里的`s​tartTime != ''`会导致OGNL尝试比较`Date`和`String`类型,从而引发异常[^2][^3]。 #### ✅ 正确解决方案 ##### 方案1:仅检查null(推荐) 直接移除对空字符串`''`的判断,仅保留`null`检查: ```xml <select id="findRecords" resultType="Record"> SELECT * FROM table WHERE 1=1 <!-- 正确写法:仅检查null --> <if test="startTime != null"> AND create_time >= #{startTime} </if> </select> ``` 这是最简洁安全的做法,完全避免类型冲突[^2][^4]。 ##### 方案2:升级MyBatis(兼容性方案) 在MyBatis 3.3.0+版本中,可通过**显式指定jdbcType**绕过此问题: ```xml <if test="startTime != null and startTime != ''"> AND create_time >= #{startTime, jdbcType=TIMESTAMP} </if> ``` 但这种方法仍需谨慎使用,建议优先选择方案1[^4]。 #### 根本原因与最佳实践 1. **版本差异**: MyBatis 3.3.0+ 强化了类型检查,旧版本可能不会报错但存在隐患[^4] $$ \text{MyBatis} \begin{cases} \text{<3.3.0} & \text{可能不报错} \\ \text{≥3.3.0} & \text{严格类型检查} \end{cases} $$ 2. **防御式编程**: 在Java层处理参数转换更可靠: ```java // Service层预处理:将空字符串转为null if ("".equals(param.getStartTimeStr())) { param.setStartTime(null); } ``` 3. **类型处理器**: 考虑实现自定义`TypeHandler`统一处理日期转换: ```java public class DateTypeHandler extends BaseTypeHandler<Date> { @Override public void setNonNullParameter(...) { /* 转换逻辑 */ } } ``` #### 总结建议 | 方案 | 安全性 | 兼容性 | 推荐指数 | |------|--------|--------|----------| | 仅检查`!= null` | ⭐⭐⭐⭐ | 全版本 | ✅✅✅ | | 指定`jdbcType` | ⭐⭐ | ≥3.3.0 | ✅✅ | | 预处理参数 | ⭐⭐⭐ | 全版本 | ✅✅✅ | > **关键结论**:删除动态SQL中`Date`类型与空字符串`''`的比较操作是根本解决方案[^1][^2]。参数空值处理应在Java业务层完成,而非SQL映射层。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值