MyBatis | 검색 결과를 임의의 Java 오브젝트에 매핑 | SELECT를 나누어 실행하기

단일 오브젝트 맵핑에서 SELECT를 나누어 실행

소스 코드

sample_mapper.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="sample.mybatis">

  <resultMap type="sample.mybatis.Foo" id="fooResultMap">
    <id property="id" column="id" />
    <association property="bar" column="bar_id" select="selectBar" />
  </resultMap>

  <select id="selectFoo" resultMap="fooResultMap">
    select * from foo_table
  </select>

  <select id="selectBar" resultType="sample.mybatis.Bar">
    select * from bar_table where id = #{id}
  </select>
</mapper>

selectFoo의 실행 결과

[DEBUG] s.m.selectFoo   - ==>  Preparing: select * from foo_table 
[DEBUG] s.m.selectFoo   - ==> Parameters: 
[DEBUG] s.m.selectBar   - ====>  Preparing: select * from bar_table where id = ? 
[DEBUG] s.m.selectBar   - ====> Parameters: 1(Integer)
[DEBUG] s.m.selectBar   - <====      Total: 1
[DEBUG] s.m.selectBar   - ====>  Preparing: select * from bar_table where id = ? 
[DEBUG] s.m.selectBar   - ====> Parameters: 2(Integer)
[DEBUG] s.m.selectBar   - <====      Total: 1
[DEBUG] s.m.selectBar   - ====>  Preparing: select * from bar_table where id = ? 
[DEBUG] s.m.selectBar   - ====> Parameters: 3(Integer)
[DEBUG] s.m.selectBar   - <====      Total: 1
[DEBUG] s.m.selectFoo   - <==      Total: 3
Foo [id=3, bar=Bar [id=1]]
Foo [id=2, bar=Bar [id=2]]
Foo [id=1, bar=Bar [id=3]]

설명

  • foo_table을 검색한 후에 각 열에 대해 bar_table 검색을 별도로 수행하고 있다.
  • <association> 태그의 select 속성에 <select> 태그의 Statement ID를 지정하는 것으로, 이런 검색을 할 수 있다.
  • column 속성에는 자식 테이블의 JOIN을 사용하는 컬럼을 지정한다.

JOIN 키가 여러 개 있는 경우

DB 테이블

foo_table

id bar_key1 bar_key2
1 2 hoge
2 1 fuga
3 1 hoge

bar_table

key1 key2
1 fuga
1 hoge
2 hoge

소스 코드

Bar.java

package sample.mybatis;

public class Bar {
    private int key1;
    private String key2;

    @Override
    public String toString() {
        return "Bar [key1=" + key1 + ", key2=" + key2 + "]";
    }
}

sample_mapper.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="sample.mybatis">

  <resultMap type="sample.mybatis.Foo" id="fooResultMap">
    <id property="id" column="id" />
                                <!-- 키가 여러 개인 경우의 지정 방법 -->
    <association property="bar" column="{key1=bar_key1,key2=bar_key2}" select="selectBar" />
  </resultMap>

  <select id="selectFoo" resultMap="fooResultMap">
    select * from foo_table
  </select>

  <select id="selectBar" resultType="sample.mybatis.Bar">
    select *
      from bar_table
     where key1 = #{key1}
       and key2 = #{key2}
  </select>
</mapper>

selectFoo의 실행 결과

[DEBUG] s.m.selectFoo   - ==>  Preparing: select * from foo_table 
[DEBUG] s.m.selectFoo   - ==> Parameters: 
[DEBUG] s.m.selectBar   - ====>  Preparing: select * from bar_table where key1 = ? and key2 = ? 
[DEBUG] s.m.selectBar   - ====> Parameters: 1(Integer), fuga(String)
[DEBUG] s.m.selectBar   - <====      Total: 1
[DEBUG] s.m.selectBar   - ====>  Preparing: select * from bar_table where key1 = ? and key2 = ? 
[DEBUG] s.m.selectBar   - ====> Parameters: 1(Integer), hoge(String)
[DEBUG] s.m.selectBar   - <====      Total: 1
[DEBUG] s.m.selectBar   - ====>  Preparing: select * from bar_table where key1 = ? and key2 = ? 
[DEBUG] s.m.selectBar   - ====> Parameters: 2(Integer), hoge(String)
[DEBUG] s.m.selectBar   - <====      Total: 1
[DEBUG] s.m.selectFoo   - <==      Total: 3
Foo [id=2, bar=Bar [key1=1, key2=fuga]]
Foo [id=3, bar=Bar [key1=1, key2=hoge]]
Foo [id=1, bar=Bar [key1=2, key2=hoge]]

설명

  • JOIN할 때에 열이 복수 존재하는 경우는 {prop1=column1, prop2=column2} 형태로 column 속성을 지정한다.

콜렉션 맵핑에서 SELECT를 나누어 실행

소스 코드

sample_mapper.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="sample.mybatis">

  <resultMap type="sample.mybatis.Foo" id="fooResultMap">
    <id property="id" column="id" />
    <collection property="barList" column="id" select="selectBar" />
  </resultMap>

  <select id="selectFoo" resultMap="fooResultMap">
    select * from foo_table
  </select>

  <select id="selectBar" resultType="sample.mybatis.Bar">
    select * from bar_table where foo_id = #{id}
  </select>
</mapper>

selectFoo의 실행 결과

[DEBUG] s.m.selectFoo   - ==>  Preparing: select * from foo_table 
[DEBUG] s.m.selectFoo   - ==> Parameters: 
[DEBUG] s.m.selectBar   - ====>  Preparing: select * from bar_table where foo_id = ? 
[DEBUG] s.m.selectBar   - ====> Parameters: 1(Integer)
[DEBUG] s.m.selectBar   - <====      Total: 3
[DEBUG] s.m.selectBar   - ====>  Preparing: select * from bar_table where foo_id = ? 
[DEBUG] s.m.selectBar   - ====> Parameters: 2(Integer)
[DEBUG] s.m.selectBar   - <====      Total: 2
[DEBUG] s.m.selectBar   - ====>  Preparing: select * from bar_table where foo_id = ? 
[DEBUG] s.m.selectBar   - ====> Parameters: 3(Integer)
[DEBUG] s.m.selectBar   - <====      Total: 1
[DEBUG] s.m.selectFoo   - <==      Total: 3
Foo [id=1, barList=[Bar [id=1], Bar [id=2], Bar [id=3]]]
Foo [id=2, barList=[Bar [id=4], Bar [id=5]]]
Foo [id=3, barList=[Bar [id=6]]]

설명

  • <association> 때와 같은 방식으로 설정한다.
  • 지연 로드 역시 가능하다.