본문 바로가기

Language/Spring

[SQL Mapper] Mybatis의 ResultMap과 ResultType

728x90
ResultMap과 ResultType
  • 두 개 모두 SQL문 수행 결과의 반환형이라는 공통점을 가짐
  • ResultMap
    • 개발자가 xml에 임의로 정의한 형식으로 반환을 하는 것
    • 복잡한 매핑이 필요할 때 사용
      → 여러 개의 테이블을 조인, null 처리 및 특별한 변환 로직이 필요한 경우 resultMap을 사용하여 정밀한 매핑 가능
  • ResultType
    • Java의 클래스 형식으로 반환을 하는 것
      → 개발자가 생성한 클래스인 VO, DAO 등이 될 수도 있고, 자바에서 기본적으로 제공하는 Collection의 List, Map 등이 될 수도 있음
    • 단순한 매핑을 할 때 사용
    • 컬럼명이 자바 객체의 필드명과 일치할 때 resultType을 사용하면 간편하고 효율적

ResultMap
<resultMap> 태그
  • id 속성 : 해당 resultMap의 참조할 때 사용하는 식별자
    → <select> 태그에서 resultMap="id 속성에 지정한 이름"으로 사용
    → <resultMap>에서의 id는 변수의 선언이고, <select>에서 resultMap="변수"를 부르는 것과 같은 느낌
  • type 속성 : 반환할 타입 클래스의 경로 + 클래스명
    → mybatis-config.xml에서 type-alias로 지정을 해두면 모든 경로를 입력하지 않고 type-alias에서 지정한 이름으로 간단히 작성 가능
<?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="kr.co.gmcorp.mapper.BoardMapper">
    <resultMap id="boardMap" type="kr.co.gmcorp.vo.BoardVO">
        <id column="board_id" property="boardId"/>
        <result column="title" property="title"/>
        <result column="content" property="content"/>
        <result column="create_at" property="createAt"/>
        <result column="modify_at" property="modifyAt"/>
    </resultMap>
    
    <select id="selectAll" resultMap="boardMap">
		SELECT 
			board_id,
			title,
			content,
			create_at,
			modify_at
		FROM 
			board
		ORDER BY 
			create_at DESC
	</select>
</mapper>

type-alias 사용 예시

  • mybatis-config.xml
<?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" />
    </settings>
	<typeAliases>
		<typeAlias alias="boardVO" type="kr.co.gmcorp.vo.BoardVO" />
	</typeAliases>
</configuration>
  • boardMapper.xml
<?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="kr.co.gmcorp.mapper.BoardMapper">
	<resultMap id="boardMap" type="boardVO">
		<id column="board_id" property="boardId"/>
		<result column="title" property="title"/>
		<result column="content" property="content"/>
		<result column="create_at" property="createAt"/>
		<result column="modify_at" property="modifyAt"/>
	</resultMap>
</mapper>
<id>와 <result> 태그
  • <id>와 <result> 태그의 차이점은 <id> 태그로 선언한 것 DB에서 기본키(Primary Key) 역할을 하는 컬럼에 사용한다는 점
  • 즉, 기본키를 제외한 나머지 컬럼의 경우 <result> 태그를 사용하면 됨
  • column 속성 : DB의 컬럼명과 정확히 일치시켜야 함
  • property 속성 : 반환할 타입(boardVO)의 멤버 필드 이름과 정확히 일치시켜야 함
  • 단, mybatis-config.xml에서 mapUnderscoreToCamelCase를 활성화했기 때문DB의 snake_case 컬럼명자바의 camelCase 필드명으로 자동 변환하여 맵핑해줌
    Ex) board_id → boardId / create_at → createAt

ResultType
  • 개발자가 정의한 VO, DAO 같은 클래스 뿐만 아니라 자바에서 제공하는 클래스 또한(HashMap 등) 반환타입으로 설정 가능
  • 단, DB의 컬럼명과 클래스의 필드명이 완전히 일치하지 않을 경우 매핑이 제대로 되지 않아 데이터가 담기지 않음
    → DB = snake_case / Java Class = camel_case
  • 따라서, SQL문의 alias를 통해 클래스의 필드명과 정확히 일치시켜야만 매핑이 정상적으로 이루어짐
  • BoardVO.java
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
public class BoardVO {
	private Long boardId;
	private String title;
	private String content;
	private LocalDateTime createAt;
	private LocalDateTime modifyAt;
}
  • boardMapper.xml
<select id="selectAll" resultType="kr.co.gmcorp.vo.BoardVO">
    SELECT 
        *
    FROM 
        board
    ORDER BY 
        create_at DESC
</select>
  • 결과

  • mybatis SQL문 수정 및 결과
<select id="selectAll" resultType="kr.co.gmcorp.vo.BoardVO">
    SELECT 
        board_id as boardId,
        title,
        content,
        create_at as createAt,
        modify_at as modifyAt
    FROM 
        board
    ORDER BY 
        create_at DESC
</select>


ResultMap과 ResultType정리
  • 일반적으로 snake_case를 쓰는 DBcamelCase를 쓰는 Java이기 때문에 resultType을 사용할 때반드시 SQL의 alias를 써서 Java의 필드명과 일치시켜 주어야 함
  • resultMap을 사용할 경우 mapUnderscoreToCamelCase을 활성화해두면 snake_case → camelCase로 자동 변환되어 매핑이 수월
  • 일회성의 경우 resultType에서 VO 또는 HashMap으로 alias를 사용하여 매핑하고, 반복적으로 사용하는 경우 resultMap을 선언하고 사용하는 것이 유리하다고 생각 됨
728x90