iBatis - queryForMap을 사용하여 map 인스턴스 return 받기

Published on: 2010. 12. 13. 17:34 by louis.dev

흔히 iBatis를 사용하면 SqlMapClient의 queryForListqueryForObject를 많이 사용하게 됩니다.
queryForList는 select문을 통하여 여러 row를 가져올때 iBatis가 List형태로 리턴해 주고, queryForObject는 select의 where조건을 통해 하나의 row만 가져오게 됩니다.
하지만 SqlMapClient에는 이들 메소드 만큼 유용한 메소드를 지원해 주는데, 그 메소드가 바로 queryForMap입니다. SqlMapClient의 queryForMap은 select문을 통해 검색된 데이터를 map형태로 리턴해 주는 아주 유용한 메소드 입니다.

Map형태로 데이터를 가져올때 약 2가지의 방법이 있습니다.

1. column을 key로 데이터를 value로 가질때
만약 select query를 통해 검색된 데이터가 다음과 같다고 가정하겠습니다.

ex)select * from test_tb where idx = 1
 idx  name  title  contents  read_count
 1  전근재  이건뭔가요?  아..모르겠다..ㅜㅜ  100

다음과 같이 검색 되었다고 할때 key값으로는 column(idx,name, title, contents, read_count)이고 각 값들은 검색된 값(1, 전근재, 이건뭔가요?, 아 모르겠다..ㅜㅜ, 100)으로 하고 싶으면 다음과 같이 작업하면 됩니다.

<SPAN id=tx_marker_caret><?xml version="1.0" encoding="UTF-8" ?>
<sqlMap namespace="tutorial">
     <resultMap id="tutorialMap" class="java.util.HashMap">
          <result column="idx" property="idx"/>
          <result column="name" property="name"/>
          <result column="title" property="title"/>
          <result column="contents" property="contents"/>
          <result column="read_count" property="readCount" javaType="int"/>
     </resultMap>

     <select id="getBoardItem" parameterClass="int" resultMap="tutorialMap">
          SELECT *
          FROM test_tb
          WHERE idx = #idx#
     </select>
</sqlMap></SPAN>


위와 같이 설정한후 queryForObject객체로 데이터를 가져 오면 됩니다.
ex)return (Map<String,Object>) getSqlMapClient().queryForObject( "tutorial.getBoardItem", idx);

위의 result의 property속성이 map의 key가 됩니다. 즉 return을 통해 map을 받았으면, map.get("read_count") 가 아니라 map.get("readCount")로 데이터를 가져옵니다.

또한 resultMap의 read_count에는 javaType으로 int형이 선언되어 있는데, 만약 이렇게 지정하지 않으면, iBatis가 숫자형을 BigDecimal로 지정하여 나중에 타입형변환을 하면 문제를 일으킵니다.(BigDecimal은 int형으로 형변환 할수 없다.. 뭐 이렇게 나오죠... 이거때문에 많이 삽질했습니다..ㅜㅜ)


2. 특정 column의 데이터를 key로 또 다른 특정 column을 value로 지정 할때
다음과 같은 select query가 있다고 하겠습니다.

ex) select name, ssn from test_tb;
 name  ssn
 태연  111111-2222222
 김태희  222222-3333333
 이민정  333333-4444444
로 데이터가 검색 되었다고 가정 하겠습니다.

만약 name의 값들을 key로 사용하고 ssn의 값들을 value로 사용하려고 하면, queryForMap을 사용하면 됩니다.
<?xml version="1.0" encoding="UTF-8" ?>
<sqlMap namespace="tutorial">
     <select id="getUserMap" resultClass="java.util.HashMap">
          SELECT name,ssn
          FROM test_tb
     </select>
</sqlMap>

위와 같이 select문을 구성합니다.
그리고 dao에서 SqlmapClient 인스턴스의 queryForMap 메소드를 이용하여 map을 return 받습니다.

ex) return (Map) getSqlMapClient.queryForMap("tutorial.getUserMap", null, "name", "ssn");
이라고 하면 됩니다.
null은 query 문으로 전달할 파라미터가 없음으로 null을 넣은 것이고, 널 다음의 인자가 key를 나타내는 column, 그 다음인자가 value를 나타내는 column 명을 입력하시면 됩니다.

만약 이때 이 key, value의 column명이 AS를 통해 다른이름으로 붙여 졌다면, 해당이름으로 queryForMap을 call해야 합니다.
ex) SELECT name AS n, ssn AS s FROM test_tb
라면 queryForMap("tutorial.getUserMap", null, "n", "s"); 로 실행해야 제대로 데이터를 받을 수 있습니다.

이렇게 queryForMap으로 데이터를 받으면, 해당 map에서 map.get("김태희") 는 222222-3333333 이 나올 것입니다.


자주는 아니지만 map형식으로 받을 일이 종종 있기 때문에 알아두면 다 피가되고 살이되는 정보 입니다~^^