307. Result Maps ( 결과 맵 )

2012. 6. 1. 16:26공부/MYBATIS

resultMap 은 마이바티스에서 가장 중요하고 강력한 것이여. ResultSet 으로부터 데이터를 검색하기 위해 JDBC가 필요로 하는 코드의 90%를 날려버리지. 그리고, 경우에 따라 JDBC가 지원하지 않는 것을 할 수도 있어. 사실, 복잡한 구문을 가진  join mapping 같은 것과 동등한 코드를 작성하기 위해서는 아마 수천라인의 코드로 펼쳐질 수 있을 거야. 간단한 구문의 ResultMap의 디자인을 위해 명시적은 결과 매핑이 필요하지 않아, 그리고 좀 더 복잡한 구문도 관계를 서술하는 정도 이상은 거의 필요치 않아. 

이미 명시적인 resultMap이 없는 간단히 매핑된 예제를 보았어. 예를 들면,

<select id="selectUsers" parameterType="int" resultType="hashmap">
  select id, username, hashedPassword
  from some_table
  where id = #{id}
</select>

모든 컬럼이 결과가 되는 이런 구문은 reultType에 기술된대로 HashMap의 키로 자동으로 매핑돼. 수많은 경우 매우 유용하지만, Hashmap은 매우 좋은 도메인 모델을 만들 수 없어. 너의 어플리케이션은 JavaBeans나 POJO를 도메인 모델로 사용할 가능성이 있지. 다음 JavaBean을 보자.

package com.someapp.model;
public class User {
  private int id;
  private String username;
  private String hashedPassword;
  
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String getUsername() {
    return username;
  }
  public void setUsername(String username) {
    this.username = username;
  }
  public String getHashedPassword() {
    return hashedPassword;
  }
  public void setHashedPassword(String hashedPassword) {
    this.hashedPassword = hashedPassword;
  }
}

JavaBeans 스펙대로, 위 클래스는 3개의 프라퍼티 : id, username 그리고 hashedPassword를 가지고 있어. 이것들은 정확하게 select 구문의 컬럼이름으로 매칭될거야.

이와 같은 JavaBean은 HashMap처럼 손쉽게 ResultSet으로 매핑될 수 있어

<select id="selectUsers" parameterType="int" resultType="com.someapp.model.User">
  select id, username, hashedPassword
  from some_table
  where id = #{id}
</select>

그리고 TypeAliases가 너의 친구라는 것을 기억해. 그것들을 사용해서 전체 클래스 이름을 사용하지 않도록 할 수 있어.

<!-- In Config XML file -->
<typeAlias type="com.someapp.model.User" alias="User"/>

<!-- In SQL Mapping XML file -->
<select id="selectUsers" parameterType="int" resultType="User">
  select id, username, hashedPassword
  from some_table
  where id = #{id}
</select>

이러한 경우에 마이바티스는, 보이지는 않지만, 컬럼 이름에 기반해서 JavaBean 프라퍼티에 자동으로 매핑하여 ResultMap을 생성할거야. 컬럼 이름이 정확하게 매칭되지 않는다면, 컬럼 이름에 Select 절 별명(표준 SQL 요소)을 이용해서 레이블을 매칭시킬 수 있어.

<select id="selectUsers" parameterType="int" resultType="User">
  select
    user_id             as "id",
    user_name           as "userName",
    hashed_password     as "hashedPassword"
  from some_table
  where id = #{id}
</select>

ResultMap의 환상적인 점은, 네가 이미 그것들에 대해서 많은 것을 배웠고, 아직 하나를 보지 못했을 뿐이라는 거야. 이러한 간단한 케이스들은 여기서 본 것 이상의 것들을 필요로 하지 않아. 예제를 살짝 흔들어보면, 이 마지막 예제가 외부의 resultMap 처럼 보이고,이는  컬럼 미스매치를 해결하는 다른 방법이야.

<resultMap id="userResultMap" type="User">
  <id property="id" column="user_id" />
  <result property="username" column="user_name"/>
  <result property="password" column="hashed_password"/>
</resultMap>

그리고 그것을 참조하는 구문은 그렇게 하기 위해 resultMap 속성을 사용해 ( resultType 을 제거했다는것을 주목해 ) 예를 들면

<select id="selectUsers" parameterType="int" resultMap="userResultMap">
  select user_id, user_name, hashed_password
  from some_table
  where id = #{id}
</select>

세상이 항상 이렇게 간단했다면 좋았을텐데.