-
myBatis LocalDate , LocalDatetime 바인딩하는 법Spring 2020. 11. 15. 19:48
mybatis를 사용하면서
Request Dto의 날짜 필드를 매번 String으로 받아서 사용했었다.
왜냐하면 mybatis에서 #{regDate} or #{regDateTime}이 같이 바인딩이 안되기 때문이었다.
아래와 같은 에러 발생
Field error in object 'testModel' on field 'regDate': rejected value [2020-01-01]; codes [typeMismatch.testModel.regDate,typeMismatch.regDate,typeMismatch.java.time.LocalDate,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [testModel.regDate,regDate]; arguments []; default message [regDate]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDate' for property 'regDate'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDate] for value '2020-01-01'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2020-01-01]]]
해결 방법
요약 : MyBatis Typehandlers JSR310 의존성을 추가해준다.
의존성 추가 필요
- MyBatis는 버전 3.4.5부터 기본적으로 JSR-310 지원
maven일 경우
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-typehandlers-jsr310</artifactId> <version>1.0.2</version> </dependency>
gradle일 경우
compile("org.mybatis:mybatis-typehandlers-jsr310:1.0.2")
현재 mybatis 버전 및 의존성 추가 상태
-마이바티스 버전이 3.4.5 이하임.
mybtis-config
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <setting name="mapUnderscoreToCamelCase" value="true" /> <setting name="cacheEnabled" value="false" /> <setting name="useGeneratedKeys" value="true" /> <setting name="defaultExecutorType" value="reuse" /> <setting name="aggressiveLazyLoading" value="false"/> </settings> <typeHandlers> <typeHandler handler="org.apache.ibatis.type.LocalDateTypeHandler" /> </typeHandlers> </configuration>
- LocalDate의 경우 "org.apache.ibatis.type.LocalDateTypeHandler" 를 추가해준다
controller
@RestController public class TestController { @Autowired private TestService testService; @GetMapping("/test") public TestResModel localDateBindTest(TestModel testModel){ System.out.println("testModel = " + testModel); TestResModel res = testService.getRegDate(testModel); System.out.println("res = " + res); return res; } }
request DTO
@Data public class TestModel { private String name; //@DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate regDate; }
- @DateTimeFormat을 적용하면 , "2020-01-40" 과 같은 파라미터에대해 400 에러를 내려준다 (type=Bad Request, status=400)
response DTO
@Data public class TestResModel { private LocalDate regDate; }
mapper
<mapper namespace="test"> <select id="getRegDate" parameterType="com.choimin.urlshort.model.TestModel" resultType="com.choimin.urlshort.model.TestResModel"> select reg_date from test where reg_date =#{regDate} limit 1 </select> </mapper>
결과
- mybatis xml에 파라미터 LocalDate가 정상적으로 바인딩되며, response 또한 LocalDate로 바인딩이 정상적으로 되는 것을 볼 수 있다.
참고
github.com/mybatis/typehandlers-jsr310
mvnrepository.com/artifact/org.mybatis/mybatis-typehandlers-jsr310/1.0.2
'Spring' 카테고리의 다른 글
Enum 유효성 검사하기 (2) 2021.08.23 Spring Cloud Config 설정값 변경 후 반영하는 방법 (0) 2021.06.03 spring batch 링크모음 (0) 2020.04.21 Gradle 인식못할 때 (0) 2020.04.02 @Valid 와 @ControllerAdvice로 DTO 예외처리하기 (3) 2020.01.12