일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- mysql polygon
- 위경도계
- 하이버네이트
- 여행
- JPA
- QGIS
- mybatis polygon
- JSON 변환
- 자바
- 사진
- mybatis polygon mapper
- spring
- 캘리그라피
- Hibernate
- cubrid
- 단축키
- json parser
- 좌표계변환
- 파이어폭스41
- Java
- 큐브리드
- shortcuts
- 좌표변환
- mybatis
- 쿼리
- join
- IntelliJ
- 엽서
- Query
- mysql gis
- Today
- Total
쏘댕
[MyBatis] resultMap collection 본문
resultMap에 클래스를 맵핑할때 인자로 다른 클래스가 있을 경우 어떻게 받아올지 찾다가 발견!
mybatis에서 테이블간의 1:N관계를 select 할때 resultMap을 통한 일종의 서브쿼리 형식으로 데이터를 가져올수 있다. 예를들어 게시판(BOARD)라는 테이블과 댓글(COMMENT)라는 테이블이 있고, 하나의 게시글에는 여러개의 댓글이 생성될수 있음으로 게시판과 댓글의 관계는 1:N관계이다. 이런 구조를 자바 코드로 클래스를 만들어 보면 다음과 같다.
1 2 3 4 5 6 7 8 9 | class Board{ private String board; private String title; private String content; private String writer; private List<Comment> comments; //getter, setter 생략 } |
소스에서도 볼수 있듯이 Board라는 클래스는 comment의 List형태인 comments라는 프로퍼티를 가지고 있게된다. 이렇게 1:N의 구조일때 Mybatis에서는 쿼리를 저장하는 xml파일(iBatis에서는 sqlmap으로 불렀으나 mybatis에서는 mapper라고 부름)에 resultMap 엘리먼트로 다음과 같이 설정할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | < resultMap id = "boradResult" type = "net.krespo.mybatis.Board" > < result property = "boardid" column = "BOARDID" /> < result property = "title" column = "TITLE" /> < result property = "content" column = "CONTENT" /> < collection property = "comments" column = "BOARDID" javaType = "java.util.ArrayList" ofType = "net.krespo.mybatis.Comment" select = "getCommentListById" /> </ resultMap > < select id = "getBoardById" resultMap = "boardResult" > SELECT boardid, title, content FROM board WHERE boardid = #{boardid} </ select > < select id = "getCommentListById" resultType = "net.krespo.mybatis.Comment" > SELECT commentid, boardid, writer, content FROM comment WHERE boardid = #{boardid} </ select > |
위와같이 getBoardById라는 쿼리는 게시글을 읽어올때 실행되는 쿼리이다. 이때 getBoardById는 resultMap으로 boardResult를 지정하고 있고 boardResult의 collection 선언을 통해(select="getCommentListByBoardId" 쿼리를 실행할때 parameter는 column으로 선언된 boardid를 가지고) 하위 댓글 리스트를 가져온다. 만약 댓글을 가져올때 자기가 쓴글에 자기가 쓴 댓글을 가져오려면 어떻게 해야할까? 그럴때는 boardid와 writer를 getCommentListById로 넘겨주어야 한다. 이처럼 여러개의 파라미터를 collection에서 넘길때는
column="{prop1=COLUMN1, prop2=COLUMN2}"
로 쓰면된다. . 즉
1 2 3 4 5 | < collection property = "comments" column = "{boardid=BOARDID,writer=WRITER}" javaType = "java.util.ArrayList" ofType = "net.krespo.mybatis.Comment" select = "getMyCommentListById" /> < select id = "getMyCommentListById" parameterType = "java.util.Map" resultType = "net.krespo.mybatis.Comment" > SELECT id, writer, content FROM comment WHERE boardid = #{boardid} AND writer = #{writer} </ select > |
로 쓰면 된다. 이때 select문에서 사용하는 파라미터명과 collection에서 선언한 column의 prop1, prop2명이 반드시 동일해야 한다.(column="{prop1=COLUMN1, prop2=COLUMN2}", #{prop1}, #{prop2}) 그리고 또 반드시 주의 해야 할점은 파라미터가 한개만 전달할때는(맨 첫번째 예제인 게시글에 댓글을 가져올때) getCommentListById에 parameterType을 지정하지 않아도 됐었다. 그러나 위와 같이 collection으로 파라미터를 여러개 전달해야 할때는 반드시 parameterType="java.util.Map"을 지정해 줘야 한다. 그렇지 않으면 다음과 같은 에러를 내뿜는다.
1 | Caused by: org.apache.ibatis.reflection.ReflectionException: There is no setter for property named 'boardid' in 'class java.lang.Object' |
그 다음은 내가 찾던 내용이 딱인데 iBatis여서 일단 적용해보고 다른 부분 다시 정리하는걸로!
resultMap의 property 속성 옵션 정리
ibatis에서 쿼리를 통해 실행된 결과를 리턴하는 타입을 정의하기 위한 <resultMap>을 명시한다.
[ibatis] resultClass, resultMap 사용 기본
1. <resultMap>의 <result> 옵션 값
<result property="propertyName" column="COLUMN_NAME"
[columnIndex="1"] [javaType="int"] [jdbcType="NUMERIC"]
[nullValue="-999999"] [select="someOtherSatement"] />
</resultMap>
빨간색으로 표시한 부분이 속성 값이며, [괄호]로 둘러싼 부분은 옵션이다.
<resultMap id=”get-category-result” class=”com.ibatis.example.Category”>
<result property=”id” column=”CAT_ID”/>
<result property=”description” column=”CAT_DESCRIPTION”/>
<result property=”productList” column=”CAT_ID” select=” getProductsByCatId”/>
</resultMap>
* <resultMap> 속성 값 사용 예
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="Product">
<resultMap id="getProduct" class="com.ibatis.example.Product">
<result property="prdid" column="PRD_ID"/>
</resultMap>
<resultMap id="get-category-result" class="com.ibatis.example.Category" extends="getProduct">
<result property="catid" column="CAT_ID" columnIndex="1"
javaType="int" jdbcType="NUMERIC" nullValue="-999999" />
<result property="prdnum" column="CAT_ID" select="getProductsByCatId"/>
</resultMap>
<statement id="selectCategory" resultMAP="get-category-result">
select * from CATEGORY
</statement>
<statement id="getProductsByCatId" parameterClass="java.lang.String" resultMAP="int">
select prdnum from PRODUCT where CAT_ID = #cat_id#
</statement>
</sqlMap>
<resultMap> 은 get-category-result 를 id로 가지며, com.ibatis.example.Category 를 리턴 객체로 한다.
이 <resultMap> 은 id="getProduct" <resultMap>을 상속하여, "getProduct" 의 프로퍼티들을 포함한다.
"getProduct" <resultMap> 외의 추가적으로 "catid" 와 "productList" 변수를 Category 객체에 셋팅한다.
"catid" 는 데이터베이스 컬럼 "CAT_ID" 에 매핑되며 인덱스는 "1"로 지정된다.
데이터 베이스에서 조회되는 jdbcType 은 "NUMERIC"이며, 이것을 javaType 인 "int" 형으로 변환하여 객체의 변수에 셋팅한다.
"productList"는 <statement id="getProductByCatId"> 쿼리의 결과 값을 셋팅한다. "getProductByCatId" 를 실행하기 위해서 column 값인 "CAT_ID" 가 파라미터로 넘겨준다.
[출처] 개발이 하고 싶어요
'공부 > Java' 카테고리의 다른 글
개인정보 마스킹처리 (휴대폰번호, 이메일) (0) | 2015.07.20 |
---|---|
[웹 시큐어 코딩] owasp-java-html-sanitizer 적용 (0) | 2015.07.10 |
[MyBatis] 두테이블 정보를 한개의 모델로! Join 쿼리로 받기 (0) | 2015.01.09 |
Spring MVC Interceptors Example – HandlerInterceptor and HandlerInterceptorAdapter (0) | 2014.11.13 |
MyBatis LIKE 검색 (0) | 2014.05.15 |