MyBatis 조회 결과 매핑

Yoon·2022년 12월 27일

조회 결과의 매핑

Database에서 select로 조회한 내용을 java object 즉, DTO(VO)에 매핑하는 내용에 대해 기술함.


MyBatis의 조회 결과 매핑 방식

MyBatis는 다양한 방식으로 조회 결과를 DTO(VO)에 매핑 시킬 수 있다.


기본 매핑

데이터베이스 테이블의 컬럼명과 DTO(VO)의 속성 명이 일치하면 자동으로 매핑이 된다. 이때 대소문자는 구별하지 않는다.

select * from emp

@Data
public class empList{
	private String key;
    private String name;
    private String rank;
    private String dept;
}

위와 같은 경우는 신경 쓸 부분이 없다. 아주 행복한 케이스 이다.


alias를 이용한 컬럼 명 변경

하지만 위와 같은 경우는 좀 드문 경우이다.

일반적으로 DB는 namaing rule로 _로 연결되는 snake case를 사용하지만
자바에서는 camel case를 사용한다.

ex)
snake case : sample_test
camel case : sampleTest

DB 명과 DTO(VO) 명이 다르다면

쿼리에 alias 처리를 하면 된다.

ex)
select actor_id actorId, first_name firstName, last_name lastName, last_update lastUpdate
from actor

위와같이 _(언더바) 가있는 테이블에 별칭을 java랑 맞춰 주었다.

그런데 만약 select 쿼리가 여기 저기 엄청 많다면?
쿼리마다 쫒아다니면서 alias를 달아줘야 할 것이다.
더군다나 DTO(VO)의 속성명이 변경되기라도 한다면 답도 없다.


naming rule을 모두 잘 지켰다면

DB 개발자와 자바 개발자가 모두 명명 규칙을 완벽히 잘 지켰다면 매핑은 간단히 처리가 가능하다.
다음 속성을 application.properties에 추가시켜서 한방에 매핑 시킬 수 있다.

mybatis.configuration.map-underscore-to-camel-case=true

주의할 점은 이 설정에는 눈이 없기 때문에 무조건 변경한다는 점이다. 만약 DTO의 속성 이름이 firstName이었다면 테이블의 컬럼 이름은 반드시 first_name이어야 한다.

하지만 이미 컬럼명이 제멋대로 만들어진 테이블을 이용해야 하거나 DTO에서 전혀 의외의 속성 명을 사용한다면 위 설정으로 매핑되지 않기 때문에 매우 곤란하다.


resultMap 활용

궁극적으로 안정적인 매핑을 위해서는 resultMap을 이용해서 매핑 룰을 작성해 놓는 것이다.

다음은 Country 테이블에 대한 resultMap의 예이다.

<resultMap type="Country" id="countryBase">
	<id column="Code" property="code"/>
	<result column="Name" property="name"/>
	<result column="Continent" property="continent"/>
	<result column="Region" property="region"/>
	<result column="SurfaceArea" property="surfaceArea"/>
	<result column="IndepYear" property="indepYear"/>
	<result column="Population" property="population"/>
	<result column="LifeExpectancy" property="lifeExpectancy"/>
	<result column="GNP" property="GNP"/>
	<result column="GNPOld" property="GNPOld"/>
	<result column="LocalName" property="localName"/>
	<result column="GovernmentForm" property="governmentForm"/>
	<result column="HeadOfState" property="headOfState"/>
	<result column="Capital" property="capital"/>
	<result column="Code2" property="code2"/>
</resultMap>
- <resultMap>은 하나의 매핑 정보를 작성한다.
	- type은 매핑 결과가 담길 DTO의 타입이다.
    - id는 resultMap을 구별하는 이름으로 unique 해야 한다.
    
- <id>는 primary key에 해당하는 컬럼을 설정하는 엘리먼트 이다.
	- column 속성은 테이블의 컬럼 명을 적는다.
    - property 속성은 조회 결과가 매핑될 DTO의 속성 이름이다.

- <result>는 primary key가 아닌 일반 컬럼에 대한 매핑을 처리하며 속성은 <id>와 동일하다.

resultMap을 사용할 때는 returnType 대신 resultMap 속성에 사용하려는 resultMap의 id를 넘겨주면 된다.

<select id="selectRange" resultMap="countryBase" parameterType="map">
    select * from country limit #{from}, #{perPage}
</select>

위 내용처럼 returnType을 resultMap으로 변경하면 된다.

profile
나의 공부 일기

0개의 댓글