String和Date互转:mapper.xml中或者class中

本文详细介绍在mapper.xml文件及Java类中实现String与Date类型转换的方法,包括使用to_char()函数将Date转换为字符串,以及通过SimpleDateFormat将字符串解析为Date。掌握这些技巧对于处理数据库日期字段和字符串日期格式转换至关重要。

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

String和Date互转:mapper.xml中

mapper.xml中SQL的tochar()可以把传入的date类型参数改为对应的字符串格式,这样子传入的参数不管是字符串还是Date都能调用了

select * from F where to_char(F_DATE,'yyyy-mm-dd') = #{fDate}

如果是tochar(todate())就会把日期格式取反,如2019-02-15就会变成51-20-9102

to_char(to_date(p_time,'yyyy-mm-dd hh24:mi:ss'),'yyyy-mm-dd')

 

String和Date互转:class中

从别的地方调用接口返回值是String,那么可以自己新建一个Dto,把值转化成json对象gson.fromJson

private Date commonStrToDate(String str) {
    Date date = null;
    // 将字符串格式转化成对应的Date
    if (str.equals("")) {

    }else{
        // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            date = sdf.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
    return date;
}

 

<think>好的,我现在需要帮助用户解决在MyBatis中遇到的日期类型与字符串类型比较导致的异常问题。首先,我需要回顾用户提供的错误信息之前的对话历史,确保理解问题的根源。 用户当前的异常是`org.mybatis.spring.MyBatisSystemException`,嵌套的异常指出无效的比较:`java.util.Date``java.lang.String`。同时,引用了之前的问题,其中涉及PostgreSQL的日期类型与字符类型的操作符不匹配错误。用户现在希望解决MyBatis中类似的类型不匹配问题。 首先,我需要分析错误的原因。根据引用[3][5],MyBatis在进行条件判断时,如果日期类型的参数与空字符串`''`进行比较,会引发`IllegalArgumentException`。例如,在XML中的`<if test="handlingDate != null and handlingDate != ''">`这样的条件判断,当`handlingDate`是`java.util.Date`类型时,与空字符串比较会导致类型不匹配,因为Date类型不能与String直接比较。 接下来,用户提到的另一个引用[4]中的示例代码,虽然在SQL中使用了`date(create_time) = date(#{createTime})`,但问题可能出在MyBatis的条件判断部分。同样,引用[5]指出,去掉空字符串的判断可以解决问题,这说明问题的根源在于MyBatis的动态SQL条件中的类型比较。 用户之前的问题涉及PostgreSQL的日期与字符串类型不匹配,解决方法是显式类型换或参数类型修正。现在在MyBatis中,虽然数据库不同,但问题类似,即类型不匹配导致SQL异常。 我需要考虑以下几点解决方案: 1. **去除空字符串判断**:根据引用[5],在MyBatis的条件判断中,如果参数是Date类型,与空字符串比较会导致错误。因此,用户应删除`handlingDate != ''`这样的条件,只保留非空检查。 2. **显式指定参数类型**:在MyBatis的XML映射文件中,使用`jdbcType`属性明确指定参数类型为DATE,例如`#{startDate, jdbcType=DATE}`,这有助于MyBatis正确处理类型换。 3. **使用数据库函数换**:在SQL语句中,使用数据库函数(如`DATE()`或PostgreSQL的`::date`)将传入的参数换为日期类型,避免隐式换问题。 4. **Java代码中参数类型修正**:确保传入的参数是`java.util.Date`或其子类(如`java.sql.Date`),而不是字符串,以避免类型不匹配。 5. **自定义类型处理器**:如果存在复杂的日期处理需求,可以创建自定义的MyBatis类型处理器,确保日期类型在传递到SQL时被正确换。 另外,需要注意用户提到的`org.springframework.jdbc.BadSqlGrammarException`PostgreSQL的PSQLException,这说明最终生成的SQL语法有问题,可能因为类型换不正确导致数据库拒绝执行。 综合以上分析,解决方案应集中在修正MyBatis的动态SQL条件,避免DateString的比较,并确保参数类型正确。同时,在SQL中显式换类型,或调整Java代码中的参数类型,可以消除此类异常。 最后,验证步骤也很重要,用户需要测试修改后的代码,确保SQL正确生成,并且没有类型不匹配的错误。检查日志中的SQL语句,确认日期参数被正确换为数据库接受的格式。</think>针对MyBatis中日期类型与字符串比较导致的异常问题,结合错误日志引用内容,提供以下分步解决方案: --- ### 一、核心问题定位 1. **非法类型比较**:MyBatis动态SQL中`<if>`标签对`java.util.Date`类型参数执行`!= ''`空字符串判断时触发类型冲突[^3][^5] 2. **SQL参数类型不匹配**:XML映射中参数未正确声明日期类型,导致生成SQL时出现`date`与`varchar`类型比较 3. **框架处理机制**:MyBatis 3.4.6之前版本存在日期类型与空字符串比较的兼容性问题[^5] --- ### 二、解决方案步骤 #### 方法1:修正动态SQL条件判断(推荐) ```xml <!-- 原错误写法(包含字符串空值判断) --> <if test="handlingDate != null and handlingDate != ''"> <!-- 引发非法比较 --> handlingDate = #{handlingDate} </if> <!-- 修正后(仅保留非空判断) --> <if test="handlingDate != null"> <!-- 正确过滤null值 --> handlingDate = #{handlingDate, jdbcType=DATE} </if> ``` *原理*:`java.util.Date`类型参数无法与空字符串进行逻辑比较,删除`!= ''`判断可规避类型冲突[^5] #### 方法2:显式指定参数类型 ```xml <!-- 强制声明参数为DATE类型 --> <if test="startDate != null"> AND record_date = #{startDate, jdbcType=DATE} </if> <!-- PostgreSQL类型换写法 --> <if test="endDate != null"> AND record_date <![CDATA[ <= ]]> #{endDate, jdbcType=DATE}::timestamp </if> ``` #### 方法3:Java代码层类型修正 ```java // Controller层传递参数时使用Date类型 @GetMapping("/query") public List<Record> queryRecords( @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) Date queryDate) { return service.getRecords(queryDate); } // Mapper接口明确参数类型 public interface RecordMapper { List<Record> selectByDate(@Param("queryDate") java.sql.Date queryDate); } ``` #### 方法4:数据库函数处理(跨数据库方案) ```xml <!-- 统一使用DATE()函数换 --> <if test="createTime != null"> AND DATE(create_time) = DATE(#{createTime, jdbcType=TIMESTAMP}) </if> <!-- PostgreSQL特定写法 --> <where> create_time::date = #{targetDate, jdbcType=DATE}::date </where> ``` --- ### 三、错误重现与验证 #### 错误SQL生成示例 ```sql -- MyBatis错误生成的SQL(类型不匹配) SELECT * FROM check_record WHERE record_date >= '2023-01-01' -- 参数作为字符串传递 -- 修正后的正确SQL SELECT * FROM check_record WHERE record_date >= DATE '2023-01-01' ``` #### 调试建议 1. **开启MyBatis日志**: ```properties # application.properties logging.level.com.example.mapper=TRACE ``` 2. **检查生成的SQL**: ``` DEBUG [main] c.e.m.RecordMapper.selectByDate - ==> Preparing: SELECT * FROM check_record WHERE create_time::date = ?::date DEBUG [main] c.e.m.RecordMapper.selectByDate - ==> Parameters: 2023-08-15(Date) ``` --- ### 四、进阶优化方案 #### 1. 自定义类型处理器 ```java @MappedTypes(Date.class) @MappedJdbcTypes(JdbcType.DATE) public class StrictDateTypeHandler extends BaseTypeHandler<Date> { @Override public void setNonNullParameter(PreparedStatement ps, int i, Date parameter, JdbcType jdbcType) { ps.setDate(i, new java.sql.Date(parameter.getTime())); } // 其他方法实现... } <!-- mybatis-config.xml注册处理器 --> <typeHandlers> <typeHandler handler="com.example.handler.StrictDateTypeHandler"/> </typeHandlers> ``` #### 2. SQL注入防护 ```xml <!-- 安全的时间范围查询 --> <where> <if test="beginDate != null"> AND create_time >= #{beginDate, jdbcType=DATE} </if> <if test="endDate != null"> AND create_time <![CDATA[ <= ]]> #{endDate, jdbcType=DATE} + INTERVAL '1 day' </if> </where> ``` --- ### 五、关联知识扩展 1. **PostgreSQL日期类型对照表**: | Java类型 | PostgreSQL类型 | 换示例 | |--------------------|----------------|-------------------------| | java.sql.Date | DATE | `2023-08-15` | | java.sql.Timestamp | TIMESTAMP | `2023-08-15 14:30:00` | 2. **MyBatis类型处理优先级**: ``` 参数声明(jdbcType) → 类型处理器注册 → 数据库驱动换 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值