MyBatis에서 JOIN관계의 테이블을 출력하기 위해서는 resultMap이 필요하다.
ResultMap
- 복잡한 결과 매핑을 간편하게 해주기위해 만들어진 태그다.
- myBatis에서 제공하는 자동 매핑으로 해결이 어려운 경우를 위해 구조를 설계할 수 있도록 만들어졌다.
위의 사진과 같이 테이블의 칼럼에 해당하는 변수를 직접 정의하여 매핑할 수 있다.
JOIN관계 테이블 처리를 위하여 눈여겨 볼 것은 'collection' 속성이다.
Collection&Association
collection과 association은 JOIN관계 테이블을 처리할 때 주로 사용된다.
collection은 has many, association은 has one의 상황에 쓰인다.
이 개념을 설명할 때, 주로 사용되는 개념은 학생과 시험지이다.
예를 들면, 어떤 시험지가 존재한다고 할 때, 그 시험지를 푸는 학생은 1명이다. 즉 시험지와 학생의 관계는 1:1의 관계가 성립된다. 이를 코드로 나타내었을 때, 시험지인 Sheet 클래스가 멤버 변수로 Student를 가지고 있는 것이다.
이를 has one이라 한다.
has many는 1:N 즉, 1:다수의 관계를 정의한다.
예를 들면, 시험지에는 다수의 문항이 존재한다.
시험지에 총 30문항이 존재한다고 가정해보도록 하자.
그렇다면 Sheet 클래스는 멤버변수로 문항인 pools를 가질텐데 이 때, pools는 단일 객체가 아니기때문에 List<pool> 타입의 pools를 가질것이다. 시험지 하나 당 30문항, 즉 1:다수의 관계이며 이를 has many라 한다.
간단하게 말하면 selectOne은 has one, selectAll은 has many가 아닐까 생각한다.
내가 출력할 SQL문은 사용자가 물건을 구매한 구매목록이다.
SELECT I.* FROM BUYLIST B
INNER JOIN ITEM I ON B.IID=I.IID
INNER JOIN MEMBER M ON B.MID=M.MID
WHERE B.MID=#{mid}
ORDER BY BID DESC LIMIT #{startnum},5
현재 mapping 파일에 작성된 SQL문이다.
BUYLIST 테이블은
CREATE TABLE BUYLIST(
BID INT AUTO_INCREMENT PRIMARY KEY,
IID VARCHAR(50) NOT NULL,
MID VARCHAR(50) NOT NULL,
CONSTRAINT MEMBER_BUYLIST FOREIGN KEY(MID) REFERENCES MEMBER(MID) ON DELETE CASCADE
);
이렇게 이루어져 있다.
IID와 MID를 외래키로 가지며 ITEM 테이블과 MEMBER 테이블을 참조한다.
물건의 PK와 회원의 PK만을 칼럼으로 가지고 다른 테이블을 참조하여
특정 회원이 구매한 물건의 품목을 받아오는 형태이다.
JOIN문을 처리하기 위하여 resultMap을 작성해보자.
그 전에 BuyListVO의 멤버 변수로 JOIN하고있는 테이블의 VO를 추가한다.
public class BuyListVO {
private int bid;
private String iid;
private String mid;
private int startnum;
private int endnum;
private MemberVO memberVO;
private ItemVO itemVO;
getter&setter는 생성되어있으며 생략하였다.
이렇게 기준이 되는 VO가 참조하는 테이블의 VO를 멤버변수로 가져야한다.
이제 resultMap을 작성해보자.
<resultMap type="buylist" id="buylistResult">
<id property="bid" column="BID"/>
<result property="iid" column="IID"/>
<result property="mid" column="MID"/>
<collection property="itemVO" resultMap="itemResult"/>
<collection property="memberVO" resultMap="memberResult"/>
</resultMap>
type은 sql-map-config.xml 파일에 정의해둔 alias이다.
buylist는 BuyListVO의 경로를 별칭으로 지정해둔것이다.
PK는 id속성으로 나타낼 수 있으며 그 외의 일반칼럼은 result로 나타낸다.
해당 SQL문은 List<> 형태로 출력되는 SQL문이다.
한 회원이 물건을 구매하지않을수도 1개만 구매할수도 여러개를 구매할수도 있기 때문에
List형태로 출력하는것이 바람직하다.
그렇기 때문에 selectAll의 형태를 띄며 참조테이블 VO를 colletion속성으로 지정해주었다.
만약 반대의 예로 어떤 주문건이 있을때 해당 주문을 한 회원을 출력한다면 association속성으로 지정하였을 것이다.
collection의 property는 내가 지정한 멤버변수의 이름이 들어간다.
다음은 collection 속성의 resultMap에 기입된 itemResult와 memberResult를 살펴보자.
<resultMap type="item" id="itemResult">
<id property="iid" column="IID"/>
<result property="iimg" column="IIMG"/>
<result property="iname" column="INAME"/>
<result property="iprice" column="IPRICE"/>
<result property="icategory" column="ICATEGORY"/>
<result property="icnt" column="ICNT"/>
<result property="idate" column="IDATE"/>
</resultMap>
<resultMap type="member" id="memberResult">
<id property="mid" column="MID"/>
</resultMap>
내가 JOIN된 SQL문을 처리하기 위하여 필요한 칼럼만 resultMap을 이용하여 지정해주면 된다.
ITEM 테이블에서는 모든 칼럼이 다 필요하기에 전부 매핑해주었고 MEMBER 테이블에서는 MID만 참조하기 때문에
MID만 매핑해준 모습이다. 이렇게 resultMap을 만들어 id를 부여하면 해당 id가 기준이 되는 resultMap안의
collection 속성에서 resultMap의 값이 된다.
이렇게 resultMap을 만들어둔 뒤에
<select id="selectAllBuyList" resultMap="buylistResult">
SELECT I.* FROM BUYLIST B
INNER JOIN ITEM I ON B.IID=I.IID
INNER JOIN MEMBER M ON B.MID=M.MID
WHERE B.MID=#{mid}
ORDER BY BID DESC LIMIT #{startnum},5
</select>
이렇게 select 태그의 결과값 속성을 resultMap으로하여 값은 위의 작성한 resultMap의 id를 기입하면 JOIN문을 처리할 수 있다.
'Mybatis' 카테고리의 다른 글
[Mybatis]MyBatis 설치 및 설정 (1) | 2022.10.04 |
---|
댓글