Mybatis、Oracle、前端传值的时间字段遭遇的坑

本文讲述了在Mybatis与Oracle配合使用时遇到的时间字段转换问题,包括java.text.ParseException和java.sql.SQLDataException异常。解决办法是确保对象字段和数据库字段都为Date类型,同时前端时间插件需设置正确格式(如yy-mm-dd)。对于字符串类型,需使用to_date转换,但直接对Date类型使用会引发错误。建议深入理解官方文档以避免类似问题。

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

首先是踩了坑花了2小时的教训才学聪明了,最好的解决方案是 将对象字段和数据库字段都设置 Date类型,这样在mybatis中可以直接比较。

当时由于idea上xml的检测机制问题,字段的重复比对需要添加注释,不然报SQl dialect no configured的error,当然你也可以把IDEA设置中File -> setting 搜索inspections,再搜索sql,找到SQL dialect detection去掉勾就行。建议加注释,规范自己。

 <select id="getRecordByDate" resultType="com.suntak.eightdisciplines.entity.Record">
        SELECT t.*
        FROM modify_complaint_history t
        WHERE 1=1
            <![CDATA[AND t.create_date >=  #{arg0,jdbcType=DATE}]]>
            <![CDATA[AND t.create_date <= #{arg1,jdbcType=DATE}]]>
    </select>

关于时间的保存基本分为4种

  • 对象字段是 String类型,数据库字段为 Date类型
  • 对象字段是 Date类型,数据库字段为 Date类型
  • 对象字段是 String类型,数据库字段为 varchar2类型
  • 对象字段是 Date类型,数据库字段为 varchar2类型

假设该时间字段名称为 create_date

刚开始我的做法是图方便,对象create_date字段设为 String,数据库create_date字段设为 varchar2

我们通常在前端使用时间插件传入值,这里我用的是jquery datepicker,注意把时间格式设置成 yy-mm-dd,这种格式在后台进行再次转换不会报错,不然 默认的‘mm/dd/yy’的格式会因为格式不匹配,用 simpleFormat.parse方法转换有问题;

这里由于前端传过来的是字符串,是需要后台进行转换成Date类型的

    @ResponseBody
    @PostMapping("/records")
    public Msg findRecords(@RequestParam(value="pn",defaultValue="1") Integer pn,
                           @RequestParam("startdate") String startdate, 
    @RequestParam("enddate") String enddate)  throws  Exception{
        System.out.println("startdate : " + startdate + "enddate :" + enddate);
        PageHelper.startPage(pn,5);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<Record> list = 
        recordService.getRecordByDate(sdf.parse(startdate),sdf.parse(enddate));
        PageInfo<Record> page = new PageInfo<Record>(list,5);
        return Msg.success().add("pageInfo", page);
    }

会报 java.text.ParseException: Unparseable date: "04/07/2019" 异常

所以需要前端传时间的参数值是 需要在 前端时间插件 中设置成 常用的时间格式

$(".choosedate").datepicker({dateFormat: "yy-mm-dd"});

将其转换成固定格式的Date类型对象字段就可以直接进行比较了,如果是固定格式的字符串怎么办呢?

  <![CDATA[AND t.create_date >= TO_DATE( #{arg0,jdbcType=DATE}, 'yyyy-mm-dd hh24:mi:ss')]]>
  <![CDATA[AND t.create_date <= TO_DATE( #{arg1,jdbcType=DATE}, 'yyyy-mm-dd hh24:mi:ss')]]>

用to_date的转换吧,但是如果本身传入的字段就是date类型的话就会报错了

会报 java.sql.SQLDataException: ORA-01861: 文字与格式字符串不匹配 异常

ORACLE官方文档

Propose

TO_DATE converts char of CHARVARCHAR2NCHAR, or NVARCHAR2 data type to a value of DATE data type.

它是将一个 字符串 类型的数据转换成 Date 类型,其他类型的转化会报不匹配的错误 ,平时看的比较多的是 to_date(sysdate,'yyyy-mm-dd') 就以为,to_date函数是将date类型的数据转换指定格式的date了,看来还是得系统的看看官方文档呀。

对了,还有 js给前端时间插件赋值格式的问题


    $(function(){
        var  nowday = new Date().format("yyyy-MM-dd");
        $("#startdate").val(nowday);
        $("#enddate").val(nowday);
    });

    Date.prototype.format =function(format)
    {
        var o = {
            "M+" : this.getMonth()+1, //month
            "d+" : this.getDate(), //day
            "h+" : this.getHours(), //hour
            "m+" : this.getMinutes(), //minute
            "s+" : this.getSeconds(), //second
            "q+" : Math.floor((this.getMonth()+3)/3), //quarter
            "S" : this.getMilliseconds() //millisecond
        }
        if(/(y+)/.test(format)){
            console.log(RegExp.$1.length);
            format=format.replace(RegExp.$1,(this.getFullYear()+"").substr(4- RegExp.$1.length));
        }
        for(var k in o){
            if(new RegExp("("+ k +")").test(format)){
                format = format.replace(RegExp.$1,RegExp.$1.length==1? o[k] : ("00"+ o[k]).substr((""+ o[k]).length));
            }
        }
        return format;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值