객체 안에 객체 Mapping

EUNJI LEE·2023년 7월 11일
0

MyBatis

목록 보기
5/6
post-custom-banner

필드로 객체를 이용하는 경우

JDBC를 사용해서 DB 테이블 = Java 객체 라고 생각해서 DTO를 짰을 때는 게시판에 필요한 데이터를 사용하기 위해서 아래 코드와 같이 객체를 생성했다. 각각의 컬럼을 필드라고 생각하고 컬럼 자료형에 맞는 자료형을 사용해서 필드를 생성했다.

package com.mybatis.model.vo;

import java.sql.Date;
import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Board {
	private int boardNo;
	private String boardTitle;
	private String boardWriter;
	private String boardContent;
	private String boardOriginalFilename;
	private String boardRenamedFilename;
	private Date boardDate;
	private int boardReadcount;
}

이 때 하나의 게시글에 작성자에 대한 정보나 게시글에 달리 댓글을 함께 출력해주려면 Member라는 객체에 사용자 정보를 담기 위해서 select문을 한 번 실행하고, 댓글들을 담기 위해서 BoardComment 객체에 담을 정보를 위해 select문을 한 번 더 실행하게 된다.
하지만 이 때 MyBatis의 <resultMap>을 활용하면 select문 하나로 하나의 객체에 연관된 테이블의 정보까지 담아올 수 있다.
우선 Board 객체 하나를 불러왔을 때 작성자의 아이디나 닉네임에 대한 정보를 담은 Member 객체가 boardWriter에 필요하고 각 게시글에는 게시글 댓글인 BoardComment 객체를 여러 개 갖게 되니 List로 BoardComment 객체를 다수로 가질 수 있다.

그래서 Board 객체를 수정해보면 아래와 같다.

package com.mybatis.model.vo;

import java.sql.Date;
import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Board {
	private int boardNo;
	private String boardTitle;
	private String boardContent;
	private String boardOriginalFilename;
	private String boardRenamedFilename;
	private Date boardDate;
	private int boardReadcount;
	private List<BoardComment> comments;
	private Member member; //boardWriter
}

이렇게 수정하면 하나의 Board 객체를 가져왔을 때 게시글을 작성한 사용자에 대한 정보들과 댓글 전체를 전부 가져올 수 있게 된다.

그럼 이렇게 작성했을 때 DB에서 값을 가져올 때는 어떻게 매핑해야 하는지 그 해결점을 resultMapassociation 태그와 collection 태그가 해결해줄 수 있다.

<association>

멤버 변수(필드)로 다른 단일 객체를 가져올 때 사용한다. mapper.xml에서 매핑 시 <association> 태그에 작성한 객체의 변수명을 property 속성 값으로 대입하고 column 대신 사용할 객체를 매핑한 resultMap을 작성해준다.

그럼 해당 객체를 매핑하기 위해서 작성한 resultMap을 실행해서 객체를 반환한다.

<collection>

다수의 객체를 멤버 변수(필드)로 가져올 때 사용한다. <collection> 태그 내에 property 속성 값으로 매핑할 변수명을 작성해주고 마찬가지로 해당 객체를 매핑한 resultMap을 작성해준다.

<!-- Board 객체 매핑 -->
<resultMap id="boardMap" type="com.web.board.dto.Board">
		<id property="boardNo" column="board_no"/>
		<result property="boardTitle" column="board_title"/>
		<result property="boardContent" column="board_content"/>
		<result property="boardOriginalFilename" column="board_original_filename"/>
		<result property="boardRenamedFilename" column="board_renamed_filename"/>
		<result property="boardDate" column="board_date"/>
		<result property="boardReadcount" column="board_readcount"/>
		<!-- memberMap 실행해서 가져옴 -->
		<association property="member" resultMap="memberMap"/>
		<!-- commentMap 실행해서 가져옴 -->
		<collection property="comments" resultMap="commentMap"/>
</resultMap>
<!-- Member 객체 매핑 -->
<resultMap id="memberMap" type="com.web.member.model.dto.Member">
		<id property="userId" column="userid"/>
		<result property="password" column="password"/>
		<result property="userName" column="user_name"/>
		<result property="gender" column="gender"/>
		<result property="age" column="age"/>
		<result property="email" column="email"/>
		<result property="phone" column="phone"/>
		<result property="address" column="address"/>
		<result property="enrolldate" column="enrolldate"/>
</resultMap>
<!-- BoardComment 객체 매핑 -->
<resultMap id="commentMap" type="com.web.board.dto.BoardComment">
		<id property="boardCommentNo" column="board_comment_no"/>
		<result property="boardCommentLevel" column="board_comment_level"/>
		<result property="boardCommentWriter" column="board_comment_writer"/>
		<result property="boardCommentContent" column="board_comment_content"/>
		<result property="boardRef" column="board_ref"/>
		<result property="boardCommentRef" column="board_comment_ref"/>
		<result property="boardCommentDate" column="board_comment_date"/>
		<association property="board" resultMap="boardMap"/>
</resultMap>

객체 내에 객체 매핑 시 SQL문

객체 내에 객체를 매핑하는 경우 하나의 select문이 실행됐을 때 가져올 데이터를 전부 조회해야 한다. 이때 연관된 FK를 사용해서 JOIN문으로 연관된 데이터를 한 번에 불러온다.

//DAO에서 selectOne 메소드로 Board 객체 하나를 반환한다.
@Override
	public Board selectBoard(SqlSession session, int no) {
		return session.selectOne("member.selectBoard",no);
	}
<select id="selectBoard" resultMap="boardMap" parameterType="_int">
		SELECT *
		FROM BOARD 
			LEFT JOIN BOARD_COMMENT ON BOARD_NO=BOARD_REF
			JOIN MEMBER ON BOARD_WRITER=USERID
		WHERE BOARD_NO=#{no}
</select>
profile
천천히 기록해보는 비비로그
post-custom-banner

0개의 댓글