mybatis中使用Java8的日期LocalDate、LocalDateTime

时间:2021-06-03 18:09:32

大家知道,在实体Entity里面,可以使用Java.sql.Date、java.sql.Timestamp、java.util.Date来映射到数据库的date、timestamp、datetime等字段

但是,java.sql.Date、java.sql.Timestamp、java.util.Date这些类都不好用,很多方法都过时了。

Java8里面新出来了一些API,LocalDate、LocalTime、LocalDateTime 非常好用

默认的情况下,在mybatis里面不支持java8的时间、日期。直接使用,会报如下错误

[java]  view plain  copy
  1. Caused by: java.lang.IllegalStateException: No typehandler found for property createTime  
  2.     at org.apache.ibatis.mapping.ResultMapping$Builder.validate(ResultMapping.java:151)  
  3.     at org.apache.ibatis.mapping.ResultMapping$Builder.build(ResultMapping.java:140)  
  4.     at org.apache.ibatis.builder.MapperBuilderAssistant.buildResultMapping(MapperBuilderAssistant.java:382)  
  5.     at org.apache.ibatis.builder.xml.XMLMapperBuilder.buildResultMappingFromContext(XMLMapperBuilder.java:378)  
  6.     at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElement(XMLMapperBuilder.java:280)  
  7.     at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElement(XMLMapperBuilder.java:252)  
  8.     at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElements(XMLMapperBuilder.java:244)  
  9.     at org.apache.ibatis.builder.xml.XMLMapperBuilder.configurationElement(XMLMapperBuilder.java:116)  
  10.     ... 81 common frames omitted  

解决方法如下:

直接加入如下依赖

[html]  view plain  copy
  1. <dependency>  
  2.     <groupId>org.mybatis</groupId>  
  3.     <artifactId>mybatis-typehandlers-jsr310</artifactId>  
  4.     <version>1.0.1</version>  
  5. </dependency>  
配置好这个依赖之后,就可以把Entity里面的Date替换成LocalDate、LocalDateTime了,其他的不用改

[java]  view plain  copy
  1. public class User {  
  2.     private Integer id;  
  3.     private String name;  
  4.     private LocalDate createDate;  
  5.     private LocalDateTime createTime;  
  6. }  

我个人的测试核心代码:

首先创建表:

create table tb_java8date (id int not null primary key auto_increment, t_datetime datetime);


mapper层: 
 
 
<?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.mmall.dao.DateTestMapper">
    <insert id="insert" parameterType="com.mmall.pojo.DateTest">
        INSERT INTO tb_java8date (id,  t_datetime)
        VALUES ( #{id,jdbcType=INTEGER},  /*#{tDateTime,jdbcType=TIMESTAMP}*/ now() )
    </insert>
</mapper>

dao层:
package com.mmall.dao;

import com.mmall.pojo.DateTest;

public interface DateTestMapper {

    int insert(DateTest record);
}
pojo层:

package com.mmall.pojo;

import java.time.LocalDateTime;

public class DateTest {
    private Integer id;
    private LocalDateTime tDateTime;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public LocalDateTime gettDateTime() {
        return tDateTime;
    }

    public void settDateTime(LocalDateTime tDateTime) {
        this.tDateTime = tDateTime;
    }
}
测试代码,比较懒+新手,直接在原来订单项目加了一个Controller。
package com.mmall.controller.portal;

import com.mmall.common.Const;
import com.mmall.common.ResponseCode;
import com.mmall.common.ServerResponse;
import com.mmall.dao.DateTestMapper;
import com.mmall.pojo.DateTest;
import com.mmall.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.Date;

@Controller
@RequestMapping("/cart/")
public class CartTestController {
    @Autowired
    private DateTestMapper dateTestMapper;

    @RequestMapping("add1.do")
    @ResponseBody
    public ServerResponse add(HttpSession session) {
        User user = (User) session.getAttribute(Const.CURRENT_USER);
        if (user == null) {
            return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(), ResponseCode.NEED_LOGIN.getDesc());
        }
        DateTest dateTest=new DateTest();
//按照需求 是否在此设置当前日期时间 或者 在mapper中直接用mysql获取当前日期时间的函数 now( )
//        dateTest.settDateTime(LocalDateTime.now());
        int rowCount=dateTestMapper.insert(dateTest);
        if (rowCount>0){
            return ServerResponse.createBySuccessMessage("插入LocalDateTime成功");
        }
        return ServerResponse.createByErrorMessage("插入LocalDateTime失败");
    }
}


以上仅在mybatis 3.4.0版本中测试有效


如果使用的mybatis版本低于3.4.0,则还需要配置如下

[html]  view plain  copy
  1. <typeHandlers>  
  2.     <typeHandler handler="org.apache.ibatis.type.InstantTypeHandler" />  
  3.     <typeHandler handler="org.apache.ibatis.type.LocalDateTimeTypeHandler" />  
  4.     <typeHandler handler="org.apache.ibatis.type.LocalDateTypeHandler" />  
  5.     <typeHandler handler="org.apache.ibatis.type.LocalTimeTypeHandler" />  
  6.     <typeHandler handler="org.apache.ibatis.type.OffsetDateTimeTypeHandler" />  
  7.     <typeHandler handler="org.apache.ibatis.type.OffsetTimeTypeHandler" />  
  8.     <typeHandler handler="org.apache.ibatis.type.ZonedDateTimeTypeHandler" />  
  9. </typeHandlers>