上一篇文章讲到 oracle存储时间类型 date 和 timestamp区别
一、前后端怎么配和传值,后端怎么处理日期才能把理想目标日期写入数据库中
这一篇文章主要侧重两方便 ,
第一方面为: 前端往后端传值以及后台返回日期给前台显示
第二方面为: 后端对日期如何进行相应的处理并正确写入数据库中
二、先搭建框架
(本文只探讨时间格式的处理,对于怎么连接数据库请自行百度)
2.1建表:
CREATE TABLE date_exaple(
ID NUMBER(4),
date_str varchar2(10),
d1 DATE,
date_date DATE,
date_time DATE,
date_stamp DATE,
time_stamp TIMESTAMP(4),
time_stamp_str TIMESTAMP(4),
)
2.2新建Entity DateEntity.Java
package com.example.modules.dateExample.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import java.sql.Timestamp;
import java.util.Date;
public class DateEntity {
private Integer id;
private String dateStr; //接收String字符串日期保存为varchar格式
@DateTimeFormat(pattern = "yyyy-MM-dd'T' HH:mm:ss.SSSZ")
@JsonFormat(pattern = "yyyy-MM-dd'T' HH:mm:ss.SSSZ")
private Date d1_str; //接收前端带毫秒精度的String日期
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date date_Date_Str; //接收前端带秒精度的String日期
//@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date date_Date_Str_Exp;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date date1; //接收前端时间戳格式日期 返回前端特顶格式日期
private Timestamp timestamp;
//get set方法略
2.2新建Dao层接口 Idate.Java
import com.example.modules.dateExample.entity.DateEntity;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Repository
@Mapper
public interface Idate {
int saveDate(DateEntity date);
DateEntity findDateById(Long id);
}
2.3 新建对应XML Idate.XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.modules.dateExample.dao.Idate">
<insert id="saveDate" parameterType="com.example.modules.dateExample.entity.DateEntity" >
INSERT INTO date_exaple
(
id,
date_Str,
d1,
date_date,
date_time,
date_stamp,
time_stamp,
time_stamp_str
)
VALUES
(
#{id,jdbcType=NUMERIC},
#{dateStr,jdbcType=VARCHAR},
#{date_Date_Str},
#{date1,jdbcType=DATE},
#{date1,jdbcType=TIME},
#{date1,jdbcType=TIMESTAMP},
#{timestamp,jdbcType=TIMESTAMP},
#{d1_str,jdbcType=TIMESTAMP}
)
</insert>
<select id="findDateById" resultType="com.example.modules.dateExample.entity.DateEntity">
SELECT
ID,
date_time AS date1,
date_time AS date_Date_Str_Exp
FROM date_exaple
WHERE id=#{id,jdbcType=VARCHAR}
</select>
</mapper>
2.4 新建 Controller类 DateExample.Java
package com.example.modules.dateExample.controller;
import com.example.modules.dateExample.dao.Idate;
import com.example.modules.dateExample.entity.DateEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
public class DateExample {
@Autowired
private Idate date;
@RequestMapping(value = "/date",method = RequestMethod.POST)
public DateEntity saveDate(@RequestBody DateEntity dateEntity){
System.out.printf("dateEntity"+dateEntity.toString());
date.saveDate(dateEntity);
return dateEntity;
}
@RequestMapping(value = "/date/findById/{id}",method = RequestMethod.GET)
public DateEntity findDateById(@PathVariable("id") Long id){
System.out.printf("id"+id.toString());
return date.findDateById(id);
}
}
2.5 到此,基础工作已经完成
插入数据访问链接为:http://localhost:8080/date
入参为:{"id":11,"dateStr":"2018-08-24","date":1535780308000,"d1_str":"2018-09-01T 13:38:28.234-0800","date_Date_Str":"2018-09-02 13:23:45","timestamp":1535837908234}
查询数据库查看结果
SELECT
ID,
date_str,
--TO_CHAR(date_str,'yyyy-MM-dd HH24:MI:SS') date_str,
TO_CHAR(d1,'yyyy-MM-dd HH24:MI:SS') d1,
TO_CHAR(date_date,'yyyy-MM-dd HH24:MI:SS') date_date,
TO_CHAR(date_time,'yyyy-MM-dd HH24:MI:SS') date_time,
TO_CHAR(date_stamp,'yyyy-MM-dd HH24:MI:SS') date_stamp,
TO_CHAR(time_stamp,'yyyy-MM-dd HH24:MI:SS:FF3') time_stamp,
TO_CHAR(time_stamp_str,'yyyy-MM-dd HH24:MI:SS:FF3') time_stamp_str
FROM date_exaple
查询访问链接为:http://localhost:8080/date/findById/10
返回的参数为(当然,没有数据当然不会有返回值):{
"id": 10,
"dateStr": null,
"d1_str": null,
"date_Date_Str": null,
"date_Date_Str_Exp": 1535780308000,
"date1": "2018-09-01 13:38:28",
"timestamp": null,
}
三、前端往后端传值以及后台返回日期给前台显示
3.1前台往后台传日期的格式类型
前端往后端传日期一般有两种形式,一种直接传字符串类型,一种直接传时间戳(前端获取时间戳方式 Date.parse(new Date()))
传字符串需要后端做相应处理转换为Date日期类型才能存数据库,如果传时间戳类型,后端接收参数类型为Date则不需要处理既可以存数据库,这两种传值方式前端传值与后端接受参数如下
前端传值类型 传值样式 后端接受类型 后端是否需要对传入参数处理
String "2018-08-24 14:34:45" java.util.Date 需要将String处理为Date类型
timestamp(时间戳) 1535780308000 java.util.Date 不需要处理,会自动转换为Date类型
3.2 注解 @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
在3.1中,一般为了传值日期的直观,前端都会传字符串类型的日期给后端,我后端的接受参数类型为Date肯定会报错,所以在接收参数时需要对前端传的字符串类型进行处理,那就涉及到@DateTimeFormat注解的使用,
而@JsonFormat注解则是当我们日期格式选用java.util.Date类型时,当在数据库查出值或者直接给前端返回Date日期参数时,会自动把Date时间转换为时间戳给前端,详情见2.5的返回的date_Date_Str_Exp和参数date1返回值的差别,前端当然是直接拿到可以展示的数据最好了
"date_Date_Str_Exp": 1535780308000,
"date1": "2018-09-01 13:38:28"
3.2.1 这两个注解使用注意事项
1. @DateTimeFormat和@JsonFormat如果前端传日期类型为 String时必须同时存在,否则只能传最小单位为日的格式 如(yyyy-MM-dd),如果传值String日期单位到秒或者毫秒值,必须同时存在,否则会报错
示例:
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date date_Date_Str;
2. 如有2.4中 直接 return dateEntity;的操作,那String参数注解DateTimeFormat日期格式与注解@JsonFormat日期格式要保持一致
3. 如果只是对数据库查询的之后返回给前端的日期进行展示处理则只需要@JsonFormat注解即可
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date date1;
4. 如果传值日期类型 是String类型,精度到毫秒值(只是告诉诸位支持这么传值,但是不建议用这种类型,不过对于给前端的时间处理展示到时区毫秒还是有借鉴意义)
前端传值String时间样式:"d1_str":"2018-09-01T 13:38:28.234-0800"
@DateTimeFormat(pattern = "yyyy-MM-dd'T' HH:mm:ss.SSSZ")
@JsonFormat(pattern = "yyyy-MM-dd'T' HH:mm:ss.SSSZ")
private Date d1_str;
关于这两个注解的具体其他用法参考:https://m.aliyun.com/jiaocheng/793349.html
5. 写在最后不一定不重要:一定注意在接收参数Entity的Date类型请使用 java.util.Date 而不是 java.sql.Date ,虽然使用 java.sql.Date时间不需要处理,返回给前端的就是字符串时间,但是 但是 但是 接受前端传过来的时间你会很痛苦,因为第一会 JDK 1.6之前使用会有性能问题,第二: 只能保存到日的日期,小时到秒的时间会自动被截取,保存到数据库的永远只是这样的时间 2018-09-01 00:00:00 ,小时到秒信息自动被抹掉
示例:
前端传值
{"id":11,"dateStr":"2018-08-24","date":1535780308000,"d1_str":"2018-09-01T13:38:28.234-0800","date_Date_Str":"2018-09-02 13:23:45","timestamp":1535837908234}
后端接收
Date d1_str //接收带 毫秒级精度的String日期
Date date_Date_Str //接受带秒精度的String日期
Timestamp timestamp //接受前端传的时间戳
四、后端对日期如何进行相应的处理并正确写入数据库中
4.1 此时前端传的日期格式已经成功存入我们接受参数Entity中,日期也通过注解自动转换为Date类型参数了
4.2 在Mybatis中Date数据映射类型有三种 Date Time TIMESTAMP
以下数据库字段类型为Date 映射类型为空会自动匹配Time类型(由于本人使用的是Oracle数据库,所以需要加上映射类型),其中date1在Entity中为Date类型,精度到秒(yyyy-MM-dd HH:mm:ss),timestamp在Entity为时间戳类型,精确到毫秒.具体详见2.3
映射类型 数据库表字段类型 保存格式
#{date1} Date 当不填映射类型会自动保存为yyyy-MM-dd HH:mi:ss
#{date1,jdbcType=DATE}, Date 只保存 yyyy-MM-dd 部分 小时部分被抹去
#{date1,jdbcType=TIME}, Date yyyy-MM-dd HH:mi:ss
#{date1,jdbcType=TIMESTAMP}, Date yyyy-MM-dd HH:mi:ss
#{timestamp,jdbcType=TIMESTAMP}, TIMESTAMP 精确到毫秒值 yyyy-MM-dd HH24:MI:SS:FF3