DB의 vip_post, user 테이블을 select하여 VipPost 객체로 매핑해야 한다.
VipPost 객체와 User 객체는 다음과 같다.
User 객체의 grade 필드는 Grade라는 Enum 타입이다. Grade는 다음과 같다.
그리고 select하는 SQL문은 다음과 같다.
여기서 'grade' column은 varchar타입인데 이를 자바의 Enum 타입으로 그냥 받아오려고 하면 마이바티스가 기본으로 제공하는 EnumTypeHandler가 동작한다.
그런데 기본으로 제공되는 EnumTypeHandler는 대문자인 Enum의 상수값이 그대로 DB 테이블에 저장된다. 내가 원하는 것은 Enum의 코드 값이 DB 테이블에 저장되는 것이다.
이때 필요한 것이 커스텀 typeHandler이다.
타입 핸들러를 직접 만들어서 mybatis의 config 파일에 등록만 해주면 알아서 동작한다.
여러 가지 블로그들을 찾아봤다. 보편적으로 인터페이스(여기서는 CodeEnum이라는 이름을 사용했다.)에 대한 타입핸들러를 만들고, 해당 인터페이스를 Enum 클래스가 구현하도록 만든다.(아래)
그런데 getCode를 했을 때 반환하는 code 값은 상수값의 소문자형일 뿐이다. 그래서 아래와 같이 수정했다.
아래는 CodeEnum에 대한 타입 핸들러이다.
위에서부터 천천히 읽어보면 무슨 뜻인지 유추할 수 있을 것이다.
그래도 간단히 설명해보겠다.
type 필드는 Grade 클래스를 의미하는 Class 객체이고, enumConstants 필드는 Grade 클래스의 상수값들을 갖는 배열이다.
setParameter(): Grade 타입의 객체가 DB의 데이터로 매핑될 때 동작
getResult(): DB의 데이터가 Grade 타입의 객체로 매핑될 때 동작
각 메서드들의 내부 코드들은 단순 사용법으로만 기억해도 될 것 같다.
mybatis-config.xml 파일에 아래 태그를 추가해주면 된다.
이때 주의해야할 점이 있다. mybatis 설정 xml 파일에선 태그들의 순서를 지켜야 된다.
순서는 아래와 같다.
properties, settings, typeAliases, typeHandlers,
objectFactory, objectWrapperFactory,
reflectorFactory, plugins, environments,
databaseIdProvider, mappers
즉, typeAliases 보단 아래에 있어야 하며 objectFactory보단 위에 있어야 한다.
findById() 쿼리를 다시 살펴보자.
아래는 테스트코드이다. 아직 junit을 제대로 다룰줄 몰라서 콘솔창에 찍는 방식으로 진행했다.
(테스트에 대해서는 공부를 한 뒤 따로 포스팅할 것이다.)
findById를 하고 나면 VipPost객체가 나온다. 이 객체가 User 타입의 객체를 필드로 갖는데 이 User 객체가 Grade 타입의 필드 grade를 가지고 있다.
테스트 코드를 실행해보면 내가 등록한 타입핸들러가 잘 동작하여 데이터 매핑이 잘 된 것을 확인할 수 있다.
[참고 블로그]
https://amagrammer91.tistory.com/115
https://shlee0882.tistory.com/292
https://www.holaxprogramming.com/2015/11/12/spring-boot-mybatis-typehandler/
https://umbum.dev/1122