(随笔)关于java自动以unix时间戳格式接收Date数据类型导致的sql查询时间失误问题的相关研究
前言
在进行项目开发的时候,有遇到过mapper执行sql语言查询指定时间范围内或截止时间之前的数据时不查询当天时间内不同时分秒时的数据,接口实现逻辑为前端传入Date类型(精度为yyyy-MM-dd)起止时间,mapper.xml文件中通过concat_ws方法实现时间精度转换(数据库内数据精度为yyyy-MM-dd HH:mm:ss),查询结果再通过json格式返回前端。
代码
<if test="cashierBrushListReqVO.gmtCreatedStart != null and cashierBrushListReqVO.gmtCreatedStart != ''"> AND cbc.gmt_created <![CDATA[>=]]> CONCAT_WS(' ',#{cashierBrushListReqVO.gmtCreatedStart},'00:00:00') </if> <if test="cashierBrushListReqVO.gmtCreatedEnd != null and cashierBrushListReqVO.gmtCreatedEnd != ''"> AND cbc.gmt_created <![CDATA[<=]]> CONCAT_WS(' ',#{cashierBrushListReqVO.gmtCreatedEnd},'23:59:59') </if>
package com.nuanwa.app.flow.share.cashier.vo; import com.fasterxml.jackson.annotation.JsonFormat; import com.nuanwa.app.flow.share.utils.result.PageVO; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import java.util.List; import java.util.Map; /** * @author pangyangjian * * @date 2023/6/16 */ @Data @EqualsAndHashCode(callSuper = true) @AllArgsConstructor @NoArgsConstructor @Accessors(chain = true) @ApiModel(value = "CashierBrushListReqVO对象", description = "查询接口请求参数") public class CashierBrushListReqVO extends PageVO { @ApiModelProperty(value = "商户号") private String merchantCode; @ApiModelProperty(value = "一级渠道编码") private String channelCode; @ApiModelProperty(value = "二级渠道编码") private String channelSource; @ApiModelProperty(value = "创建开始时间") @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8") private Date gmtCreatedStart; @ApiModelProperty(value = "创建结束时间") @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8") private Date gmtCreatedEnd; @ApiModelProperty(value = "商户号-一级渠道编码") private List<Map<Object,Object>> list; }
解释
已知,vo接受类中开始时间和结束时间都设置为Date类型,并且通过JsonFormat注解表明了变量的时间格式。测试数据为json格式的
{ "gmtCreatedStart": 2023-07-10, "gmtCreatedEnd": 2023-07-10 }
在查阅log输出日志后可以发现,在执行sql语句查询时间的时候判断的时间数值并不是输入的时间 2023-07-10,而是1688918400,即预期中的sql语句
AND cbc.gmt_created >= 2023-07-10 00:00:00 AND cbc.gmt_created <= 2023-07-10 23:59:59
变成了
AND cbc.gmt_created >= 1688918400 AND cbc.gmt_created <= 1688918400
在查阅了大量文献资料后得知,在idea中java接收并转换成Date类型的时间参数时自动以Unix时间戳的格式进行转换存储,即输入的2023-07-10在java中由String转换成Date类型的时候自动转换成1688918400,因此在执行mapper.xml文件中组装动态sql语句的时候出现了错误,查询语句出错自然无法查询2023-07-10 00:00:00和2023-07-10 23:59:59之间的数据。
解决方法
目前来说总体有两种解决方案:
-
改变vo接受类中相关参数的数据类型,将Date改成String类型进行存储,因此java在接收Json格式数据的时候无需将时间参数转换成Date,而是直接以String类型赋值给vo接受类中的相关参数,举例:将上段vo接受类中的开始时间和结束时间的Date类型改成String类型
@ApiModelProperty(value = "创建开始时间") @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8") private String gmtCreatedStart; @ApiModelProperty(value = "创建结束时间") @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8") private String gmtCreatedEnd; -
自定义String类型转换成Date类型方法,即通过SimpleDateFormat类进行指定时间格式的数据转换,比如说
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class Main { public static void main(String[] args) { String dateString = "2021-08-25 09:30:00"; SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { Date date = dateFormat.parse(dateString); System.out.println(date); } catch (ParseException e) { e.printStackTrace(); } } }
总结
综上所述,在进行数据接收的时候一定要注意java后端存储数据的方式。
希望这篇文章能够帮到你 :p
本文作者:Joseph·Jonardo
本文链接:https://www.cnblogs.com/Joseph-Jonardo/p/17647883.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步