일상/일기장

TIL22.02.25 - MyBatis : join

jmaster 2022. 2. 25. 22:51

포함관계 일 때의 resultMap 사용

  • DTO 클래스의 필드가 포함 관계로 작성된 경우 포함 관계의 필드에 인스턴스를 매핑하여 저장되도록 resultMap 엘리먼트를 반드시 사용하여 매핑 정보 제공
  • association : 1:1 관계의 테이블 조인 검색행의 컬럼값을 포함 관계의 인스턴스로 생성하여 DTO 클래스의 필드에 매핑하여 저장하기 위한 엘리먼트
  • → association 엘리먼트의 하위 엘리먼트(id 엘리먼트와 result 엘리먼트)로 검색행의 컬럼값을 포함 인스턴스 필드에 매핑되어 저장되도록 설정
  • property 속성 : DTO 클래스에 포함 관계로 설정된 필드명을 속성값으로 설정
  • javaType 속성 : DTO 클래스에 포함 관계로 설정된 Java 자료형을 속성값으로 설정
 
<resultMap type="MyCommentUser2" id="myCommentUser2ResultMap">
	<association property="comment" javaType="MyComment1">
		<id column="comment_no" property="commentNo"/>
		<result column="comment_id" property="commentId"/>
		<result column="comment_content" property="commentContent"/>
		<result column="comment_date" property="commentDate"/>
	</association>
	<association property="user" javaType="MyUser">
		<id column="user_id" property="userId"/>
		<result column="user_name" property="userName"/>
	</association>
</resultMap>
  • 엘리먼트에 등록된 SQL 명령에서 관계연산자(> 또는 <)를 사용하면 엘리먼트 기호로 인식되어 에러 발생
  • → SQL 명령에 XML 문서에서 사용할 수 없는 문자가 존재할 경우 엔티티 래퍼런스로 변경하거나 CDATA 세션에 SQL 명령을 등록하여 사용
//엔티티 래퍼런스로 변경 
select rownum,reply.* from (select * from myreply order by reply_no where rownum &lt;= 5;
		
//CDATA 세션 사용
<![CDATA[
    select rownum,reply.* from (select * from myreply order by reply_no where rownum &lt;= 5;	
]]>

Join1

  • 1:1 관계의 조인 방식

POJO

  • 기존에 작성된 클래스를 재사용(POJO - Plane Old Java Object)하여 새로운 클래스를 쉽게 작성해 생산성 증가 및 유지보수 효율성 증가
public class MyCommentUser2 {
    private MyComment1 comment;
    private MyUser user;
}
<resultMap type="MyReply" id="myReplyResulyMap">
    <id column="reply_no" property="replyNo"/>
    <result column="reply_id" property="replyId"/>
    <result column="reply_content" property="replyContent"/>
    <result column="reply_date" property="replyDate"/>
    <result column="reply_comment_no" property="replyCommentNo"/>
</resultMap>
  • resultMap 속성 : resultMap 엘리먼트를 구분하기 위한 식별자를 속성값으로 설정
  • →기존 매핑정보를 제공받아 검색행의 컬럼값을 포함 인스턴스 필드에 매핑 처리 - resultMap 엘리먼트의 재사용
  • column 속성 : select 속성값으로 등록된 엘리먼트의 SELECT 명령에서 사용될 컬럼값을 전달하기 위한 컬럼명을 속성값으로 설정
  • select 속성 : SELECT 명령이 등록된 select 엘리먼트의 식별자를 속성값으로 설정
  • → select 엘리먼트에 등록된 SELECT 명령을 실행하여 제공된 결과값(DTO 인스턴스)를 포함 인스턴스의 필드에 매핑하여 저장 → column 속성값으로 제공된 컬럼값을 SELECT 명령에 전달하여 조건에 맞는 행만 검색
<resultMap type="MyReplyUser" id="myReplyUserResultMap">
    <association property="reply" javaType="MyReply" resultMap="myReplyResulyMap"/>
    <association property="user" column="reply_id" select="selectMyUser"/>
</resultMap>	
<select id="selectMyUser" parameterType="string" resultType="MyUser">
    select * from myuser where user_id=#{userId}
</select>

<select id="selectReplyUserList" resultMap="myReplyUserResultMap">
    select * from myreply join myuser on reply_id=user_id order by reply_no desc
</select>

JOIN2 (1:N)

1:N 관계의 조인 방식

// => 1:N 관계의 조인 검색 결과를 저장하기 위한 클래스
public class MyCommentReply {
	//MYCOMMENT 테이블의 검색결과를 저장하기 위한 필드 - 검색행 : 1개
	private int commentNo;
	private String commentId;
	private String commentContent;
	private String commentDate;
	
	//MYREPLY 테이블의 검색결과를 저장하기 위한 필드 - 검색행 : 0개 이상
	// => 게시글에 대한 댓글목록을 저장하기 위해 List 자료형을 이용하여 필드 선언 - 포함관계
	private List<MyReply> replies;

resultMap

  • collection: 1:N 관계의 테이블 조인에서 결과를 다수의 검색결과를 List 인스턴스로 생성하여 필드에 저장하기 위한 엘리먼트
  • property 속성 : List 인스턴스를 저장하기 위한 필드명을 속성값으로 설정
  • ofType 속성 : List 인스턴스의 요소값으로 저장될 Java 자료형을 속성값으로 설정
<resultMap type="MyCommentReply" id="myCommentReplyResultMap">
		<id column="comment_no" property="commentNo"/>
		<result column="comment_id" property="commentId"/>
		<result column="comment_content" property="commentContent"/>
		<result column="comment_date" property="commentDate"/>
	<collection property="replies" ofType="MyReply">
			<id column="reply_no" property="replyNo"/>
			<result column="reply_id" property="replyId"/>
			<result column="reply_content" property="replyContent"/>
			<result column="reply_date" property="replyDate"/>
			<result column="reply_comment_no" property="replyCommentNo"/>
		</collection>
</resultMap>

 

  • 1:N 관계의 조인은 OUTER JOIN를 사용하여 검색 --> → 댓글이 없는 게시글을 검색하기 위해 LEFT OUTER JOIN 사용
<select id="selectCommentReply" parameterType="int" resultMap="myCommentReplyResultMap">
    select * from mycomment left join myreply on comment_no=reply_comment_no 
        where comment_no=#{comment_no} order by reply_no desc
</select>