MyBatis resultMap이란?
resultMap ?
MyBatis XML 파일에 쿼리를 작성하면, 쿼리 결과가 POJO 클래스에 자동으로 바인딩이 됩니다.
resultMap을 설명하기 위해서 2가지 예시를 들어서 설명하겠습니다. 첫 번째는 테이블간의 관계가 1:1인경우와, 두 번째는 테이블간의 관계가 1:N인 경우에 대한 예시를 통해서 배워봅시다.
테이블간의 관계가 1:1인 경우(association)
사용자가 이벤트에 참여하는 경우(이때 개인정보를 입력한다.) 사용자가 어떠한 이벤트에 참여했는지에 대한 정보를 가지고있는 EVENT_JOIN_USER 테이블과 개인정보를 관리하는 PRIAVCY 테이블과 EVENT_MASTER 테이블이 있다고 가정하겠습니다.
EVENT_JOIN_USER 테이블은 SEQ(인조키)를 기본키로 가지며, PRIVACY 테이블의 기본키와 EVENT_MASTER 테이블의 기본키를 외래키로 가지고있습니다.
PRIVACY 테이블은 간단하게 이름, 핸드폰, 이메일에 대한 정보를 가지고 있는 테이블입니다.
이제 위 2개의 테이블과, 두 테이블의 공통 속성을 가지고 있는 BaseVo POJO 클래스를 만들어 봅시다. 속성(필드)명은 카멜케이스(CamelCase) 규칙을 적용했습니다.
위 EventJoinUser 테이블에는 없는 컬럼이지만, EventJoinUserVo에서 개인정보 SEQ에 해당하는, 특정한 사람에 대한 name, phone에 대한 컬럼을 추가하기 위해서, name과 phone1~3을 속성으로 가지고 있는 PrivacyVo 객체를 속성으로 가지고 있습니다.
condition : EventJoinUser의 기본키 SEQ에 대해, 이벤트에 참여한 특정한 사람에 대한 정보를 얻기위한 Mapper.xml 작성
select 쿼리태그에 resultMap 속성을 추가했습니다. resultMap은 JOIN하는 POJO 클래스의 CamelCase를 적용한 클래스명 혹은 @Alias의 키값을 적으면 됩니다. 위 resultMap에 적힌 Key값으로 인해 resultMap을 통해서 POJO 클래스로 바인딩 됩니다.
resultMap을 사용할 때의 주의점은 JPA, ORM은 테이블과 클래스가 1:1로 매핑이 되지만, resultMap은 select 쿼리문에 나열된 컬럼명들이 resultMap안에 모두 선언되어있어야합니다.
따라서 위 Mapper.xml을 실행하게 되면, B.SEQ, USER_NAME과 PHONE1~3이 EventJoinUser 클래스에 선언된 privacyVo 객체 참조변수명을 통해서 바인딩 됩니다. 따라서 JSP에서는 privacyVo에 들어있는 속성을 아래와 같은 방식으로 꺼내 쓸 수 있습니다.
테이블간의 관계가 1:N인 경우(collection)
위 테이블을 예시로 그대로 가져가겠습니다.
condition : EventJoinUser테이블의 외래키 EVENT_MASTER_SEQ에 대해, 해당 이벤트에 참여한 모든 사람에 대한 정보를 얻기위한 Mapper.xml 작성
먼저 EventJoinUserVo 클래스를 보겠습니다.
1:N인 경우는 결과가 List로 나오기 때문에, PrivacyVo객체를 List로 받는 속성을 추가해줬습니다. 다음은 Mapper.xml을 보겠습니다.
EVENT_MASTER와 JOIN을 하는 조건이 추가되었습니다.
FROM 절에 적히는 테이블에 대한 조건은 WHERE 절에 작성, JOIN 절에 적히는 테이블에 대한 조건은 ON 절에 작성, ON절의 좌측은 FROM 절에 적히는 테이블의 FK, 우측은 JOIN 절에 적히는 테이블의 PK
1:1관계였던 association과 다른점은 javaType이 아닌 ofType으로 받는다는 점 입니다.
결론
MyBatis의 resultMap을 사용할 줄 알면, VO 클래스의 코드량이 줄어들 수 있고, 더욱 깔끔하게 관리할 수 있으며, 객체 혹은 List를 속성으로 가지기 때문에 의미전달도 훨씬 잘됩니다.