前言

Github:https://github.com/HealerJean

博客:http://blog.healerjean.com

项目中经常会用到与日期相关的注解,这里简单介绍下吧

第一种:——》实体类会封装成日期“yyyy-MM-dd”的 Date类型。

第二种:——》实体类会封装成时间“hh-MM-ss”的 Date类型。

第三种:——》实体类会封装成完整的时间“yyyy-MM-dd hh:MM:ss”的 Date类型。

1、@Temporal(TemporalType.DATE)

如果字段为date类型,则非常匹配,查询出来到前台的处理直接就是2019-01-24

如果数据库字段为datetime类型,则,数据库时分秒会变成00:00:00,但是到了前台只显示年月日

2、@Temporal(TemporalType.TIME)

数据库字段为datetime 类型

insert插入报错:Incorrect datetime value: ‘17:31:28’ for column ‘cdate’ at row 1

查询是没有问题的,到前台自动处理变成时分秒,如下

所以,一般不要使用它(因为就没有一个字段是只保存时分秒的,毫无意义啊~~~~)


//    {
//        "id": 1,
//            "dateT": null,
//            "dateTTime": null,
//            "dateTTimesTamp": null,
//            "dateTimeFormat": null,
//            "dateTDate": null,
//            "cdate": "17:31:28",
//            "udate": 1548322288000
//    }

//   @Temporal(TemporalType.TIME) 
    @ApiModelProperty(value = "dateTime类型 TemporalType.TIME date类型为 hh-MM-ss",dataType = "date")
    private Date dateTTime ;
    

3、@Temporal(TemporalType.TIMESTAMP)

非常正常的数据处理,返回到前台就是一个时间戳,到了库里面,年月日,时分秒

4、前面3个的总结

即使上面各有各的转化格式,但是在我们设置Controller它们所匹配的字段接收的时候,还是根据前台出来的值进行接收的(前台传来什么,我们在运行代码的时候就是什么,和上面的3中主键没有关系),只不过在入库,或者是在铺数据到前台的时候会发生一些格式转化。

4、格式化到前台,使用率非常高

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")

5、格式化到数据库

 1.	@DateTimeFormat(pattern = "yyyy-MM-dd")//存日期时使用,还是算了包。存日期我这里有问题 ,一般也没必要整这个 
 2.	private Date startTime;  

测试

1、实体类


package com.hlj.entity.db.demo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import org.hibernate.annotations.UpdateTimestamp;
import org.springframework.format.annotation.DateTimeFormat;

import javax.persistence.*;
import java.util.Date;

/**
 * 作者 :HealerJean
 * 日期 :2019/1/24  下午5:10.
 * 类描述:
 */
@Entity
@Table(name = "demo_entity_date")
@Data
@Accessors(chain = true)
@ApiModel(value = "D04-测试Temporal 日期格式问题")
public class D04DateEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @ApiModelProperty(value = "demo01update 主键")
    private Long id;

    @Temporal(TemporalType.DATE)
    @ApiModelProperty(value = "dateTime类型 TemporalType.DATE")
    private Date dateT;

//    @Temporal(TemporalType.TIME) // insert插入报错 给 字段为timestime 插入的时候回提示报错: Incorrect datetime value: '17:31:28' for column 'cdate' at row 1
//                                   查询没有问题 ,返回到前台不是时间戳了,直接就变成了如下,所以一般不要使用
//    {
//        "id": 1,
//            "dateT": null,
//            "dateTTime": null,
//            "dateTTimesTamp": null,
//            "dateTimeFormat": null,
//            "dateTDate": null,
//            "cdate": "17:31:28",
//            "udate": 1548322288000
//    }
    @ApiModelProperty(value = "dateTime类型 TemporalType.TIME",dataType = "date")
    private Date dateTTime ;

    @Temporal(TemporalType.TIMESTAMP)
    @ApiModelProperty(value = "dateTime类型 TemporalType.TIMESTAMP")
    private Date dateTTimesTamp ;

    @DateTimeFormat(pattern="yyyy-MM-dd")
    @ApiModelProperty(value = "dateTime类型 测试DateTimeFormat")
    private Date dateTimeFormat ;

    @ApiModelProperty(value = "数据库中存放的就是 date类型")
    private Date dateTDate ;

    @Column(insertable = true,updatable = false)
    private Date cdate;

    @UpdateTimestamp
    private Date udate;

}


/**
 *
 第一种:@Temporal(TemporalType.DATE)——》实体类会封装成日期“yyyy-MM-dd”的 Date类型。
 第二种:@Temporal(TemporalType.TIME)——》实体类会封装成时间“hh-MM-ss”的 Date类型。
 第三种:@Temporal(TemporalType.TIMESTAMP)——》实体类会封装成完整的时间“yyyy-MM-dd hh:MM:ss”的 Date类型。





 CREATE TABLE `demo_entity_date` (
 `id` bigint(20) NOT NULL AUTO_INCREMENT,
 dateT datetime ,
 dateTTime datetime ,
 dateTTimesTamp datetime ,
 dateTimeFormat datetime,
 dateTDate date,
 `cdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
 `udate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 PRIMARY KEY (`id`) );

 */

2、controller

package com.hlj.moudle.jpacru.controller;

import com.hlj.dao.db.D05DateEntityRepository;
import com.hlj.entity.db.demo.D04DateEntity;
import com.hlj.moudle.jpacru.service.D05DateService;
import io.swagger.annotations.*;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 作者 :HealerJean
 * 日期 :2019/1/24  下午5:04.
 * 类描述:
 */
@ApiResponses(value = {
        @ApiResponse(code = 200, message = "访问正常"),
        @ApiResponse(code = 301, message = "逻辑错误"),
        @ApiResponse(code = 500, message = "系统错误"),
        @ApiResponse(code = 401, message = "未认证"),
        @ApiResponse(code = 403, message = "禁止访问"),
        @ApiResponse(code = 404, message = "url错误")
})
@Api(description = "Date类型的格式化")
@Controller
@RequestMapping("jpa/date")
public class D05DateController {

    @InitBinder
    public void dateBinder(WebDataBinder binder){
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        binder.registerCustomEditor(Date.class,new CustomDateEditor(dateFormat,true));
    }

    @Resource
    private D05DateService dateService ;

    @Resource
    private D05DateEntityRepository d05DateEntityRepository;

    @GetMapping("addD04DateEntity")
    @ResponseBody
    public D04DateEntity addD04DateEntity(D04DateEntity d04DateEntity){
        return   dateService.addD04DateEntity(d04DateEntity) ;
    }


    @GetMapping("findById")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id",value = "主键Id",defaultValue = "1",required = true,dataType = "long",dataTypeClass = Long.class,paramType = "query"),
    })
    public D04DateEntity findById(Long id){
        return   d05DateEntityRepository.findOne(id) ;
    }



}

3、service

@Service
@Slf4j
public class D05DateServiceImpl implements D05DateService {

    @Resource
    private D05DateEntityRepository d05DateEntityRepository;


    public  D04DateEntity addD04DateEntity (D04DateEntity d04DateEntity){
        d05DateEntityRepository.save(d04DateEntity);
        return  d04DateEntity ;
    }

}

4、测试

4.1、添加

WX20190124-180247@2x

http://localhost:8080/jpa/date/addD04DateEntity?dateT=2019-01-24%2017%3A31%3A28&dateTTime=2019-01-24%2017%3A31%3A28&dateTTimesTamp=2019-01-24%2017%3A31%3A28&dateTimeFormat=2019-01-24%2017%3A31%3A28&dateTDate=2019-01-24%2017%3A31%3A28&cdate=2019-01-24%2017%3A31%3A28&udate=2019-01-24%2017%3A31%3A28

保存并返回实体的结果如下,没有看到上面的@Temporal(TemporalType.DATE)起作用

{
  "id": 2,
  "dateT": "1548322288000",
  "dateTTime": 1548322288000,
  "dateTTimesTamp": 1548322288000,
  "dateTimeFormat": 1548322288000,
  "dateTDate": 1548259200000,
  "cdate": 1548322288000,
  "udate": 1548323059000
}

2、查看 http://localhost:8080/jpa/date/findById?id=2

这才提现出来,说明上面的@Temporal 只针对从数据库中查询处理的格式转化有效,所以,还是建议不使用它了。

### 
{
  "id": 2,
  "dateT": "2019-01-24",
  "dateTTime": 1548322288000,
  "dateTTimesTamp": 1548322288000,
  "dateTimeFormat": 1548322288000,
  "dateTDate": 1548259200000,
  "cdate": 1548322288000,
  "udate": 1548323059000
}

3、使用@JsonFormat 完美控制器

   @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @Column(insertable = true,updatable = false)
    private Date cdate;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @UpdateTimestamp
    private Date udate;

保存并返回的实体如下

{
  "id": 3,
  "dateT": 1548322288000,
  "dateTTime": 1548322288000,
  "dateTTimesTamp": 1548322288000,
  "dateTimeFormat": 1548322288000,
  "dateTDate": 1548322288000,
  "cdate": "2019-01-24 17:31:28",
  "udate": "2019-01-24 18:12:28"
}

根据id查询返回的结果如下

{
  "id": 3,
  "dateT": "2019-01-24",
  "dateTTime": 1548322288000,
  "dateTTimesTamp": 1548322288000,
  "dateTimeFormat": 1548322288000,
  "dateTDate": 1548259200000,
  "cdate": "2019-01-24 17:31:28",
  "udate": "2019-01-24 18:04:46"
}

总结:

哥们试了试,如果上面的@JsonFormat 和@Temporal 叠加使用

如果Temporal是 @Temporal(TemporalType.TIMESTAMP)JsonFormat优先

如果是 @Temporal(TemporalType.DATE),则是@Temporal优先

正如上面的,我们灵活使用,好处有很多,如果以后我们统一给前台返回的是正规军,则建议年月日的使用@Temporal(TemporalType.DATE)

其他有时分秒的使用@JsonFormat 甚至都可以使用它

@Temporal以后项目中可以不使用,因为mysql会自动帮我们识别。除非必要转化,比如非要将datetime的时分秒去掉变成00:00:00 使用@Temporal(TemporalType.DATE) ,否则正常设计就想好怎么使用。

ContactAuthor