[Mybatis] 1:N resultMap collection

John·2022년 1월 25일
2

개발 메모🌷

목록 보기
1/13
post-thumbnail

정규직 전환 후 첫 업무를 받았습니다. 그러던 중 쿼리를 짜면서 중 각 매장의 대표상품 실적 조회쿼리 부분에서 고민이 생겼습니다.

각 매장의 대표 상품을 가져올 때, 1:N 관계이기 때문에 매장의 데이터가 중복되어 조회됩니다.

중복되는 데이터를 효율적으로 관리하기 위해 resultMap을 사용하여 개발을 진행했으며, 공부한 내용을 기록해 보겠습니다.


요구사항

메인 페이지의 가입 상품 항목 추가 및 날짜 기준 월 실적 추가
매장 페이지의 각 매장의 가입 상품 리스트 추가 그리고 날짜 기준 월 실적 추가 및 상품 가입자 수 추가


1:N

매장의 정보를 담은 storeItems와 maxIndex를 내려줍니다.

storeItems는 매장의 정보와 함께 매장의 가입 상품의 정보를 담은 promtItems를 포함합니다.

promtItems는 매장 정보가 중복으로 조회가 됩니다.(1:N)

위 문제를 해결하기 위해 Mybatis resultMap의 collection을 사용하기로 했습니다.


ResultMap

데이터베이스 결과데이터를 객체에 로드하는 방법을 정의하는 엘리먼트이며, 간단한 구문에서는 매핑이 필요하지 않고 복잡한 구문에서 관계를 서술하기 위해 사용됩니다.


코드

...

<resultMap type="com.Company.Project.model.storeItems" id="storeItemsListMap">
    <id property="storeNum" column="STORENUM" />
    <result property="achieveRate" column="ACHIEVERATE" />
    <result property="baseSales" column="BASESALES" />
    <result property="goal" column="GOAL" />
    <result property="storeName" column="STORENAME" />
    <result property="seq" column="SEQ" />

    <collection property="promtItems" javaType="com.Company.Project.model.storeItems_promtItems">
        <result property="promtItemCode" column="PROMTITEMCODE" />
        <result property="promtItemBaseSales" column="PROMTITEMBASESALES" />
        <result property="promtItemName" column="PROMTITEMNAME" />
        <result property="promtStoreNum" column="PROMTSTORENUM" />
    </collection>
</resultMap>

...

<resultMap type="com.model.storeItems" id="storeItemsListMap">

type은 패키지를 포함한 자바 클래스명이나 타입별칭이며, DTO(모델)를 작성합니다..

id는 결과매핑을 참조하기 위해 사용할 수 있는 값으로 네임스페이스에서 유일한 식별자이며 임의의 이름을 작성합니다..


<id property="storeNum" column="STORENUM" />
<result property="achieveRate" column="ACHIEVERATE" />

id와 result
한개의 칼럼을 한개의 프로퍼티나 간단한 데이터 타입의 필드에 매핑

property
매핑하기 위한 필드나 프로퍼티

column
데이터베이스의 칼럼명이나 별칭된 칼럼

javaType
패키지 경로를 포함한 클래스 전체명이거나 타입 별칭

Q) id와 result의 차이점은?
A) id 값은 객체 인스턴스를 비교할 때 사용되는 구분자 프로퍼티로 처리됩니다.
위와같은 Nested select(중복 질의)에 효과적입니다.


<collection property="promtItems" javaType="com.model.storeItems_promtItems">

collection
엘리먼트는 관계를 파악하기 위해 작성


각 매장은 오직 하나의 storeNum(매장 코드)을 가지고 있습니다.
하지만 하나의 STORENUM의 다양한 promt(프로모션 상품)가 존재합니다.

이러한 1:N 관계에서 collection을 사용합니다.


⬜ 조회 쿼리

...

<select id="조회쿼리" parameterType="Map" resultMap="storeItemsListMap">            
...
</select>

...

resultMap의 결과매핑을 위한 식별자 id값을 할당시켜줍니다.


결과

1:N의 데이터는 한 번 조회되었다.

중복되는 데이터(storeNum)는 하나만 보여지며 하위의 promtList또한 제대로 출력되었다.


1:N 관계의 조회 쿼리를 공부할 수 있어서 도움이 많이 됐다.

이 외에 Mapper 부분을 더 공부하면 효율적으로 데이터를 관리할 수 있을 것 같다.

다음에는 Association 부분을 공부해봐야겠다!

여담으로 포스트맨을 통해 테스트를 진행했었는데, 이 프로젝트에선 세션을 통한 로그인을 사용한다. 그래서 포스트맨으로 테스트를 못하고있으니 사수님께서 JUNIT을 통한 테스트 방법을 알려주셨다. 또 하나 배웠다.

참고자료
Mybatis공식
N+1쿼리, Mybatis
resultMap

profile
기록을 습관으로

2개의 댓글

comment-user-thumbnail
2022년 1월 26일

저도 db 공부를 열심히 해야겠단 생각이 드네요~ 글 잘보고 갑니다^^

답글 달기
comment-user-thumbnail
2022년 2월 9일

저도 본받아서 열심히 하겠습니다!!!

답글 달기