본문 바로가기

학원/복기

[MyBatis] 조인예제(1) / association 엘리먼트

앞서 만든 테이블들을 조인해볼 것이다.

MYCOMMENT와 MYUSER 테이블을 조인시켜 사용자의 이름값을 가져와보자.

 

 

 

[MYCOMMENT 테이블]

 

[MYUSER 테이블]

 

 

이를 위해서는 이름을 저장하기 위한 필드가 필요하다.

 

MYCOMMENT 테이블과 MYUSER 테이블의 컬럼값을 저장하기 위한 DTO 클래스 [MyComment3] 을 작성해보자

 

[MyComment3] 클래스는 1 : 1 관계의 테이블 조인에 대한 검색결과를 저장하기 위한 클래스이다

package xyz.itwill.dto;

//MYCOMMENT 테이블과 MYUSER 테이블의 검색결과를 저장하기 위한 클래스
public class MyComment3 {
	//MYCOMMENT 테이블의 컬럼값을 저장하기 위한 필드 
	private int no;
	private String id;
	private String content;
	private String date;
	
	//MYUSER 테이블의 컬럼값을 저장하기 위한 필드 
	private String name;
	
	public MyComment3() {
		// TODO Auto-generated constructor stub
	}

	public int getNo() {
		return no;
	}

	public void setNo(int no) {
		this.no = no;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public String getDate() {
		return date;
	}

	public void setDate(String date) {
		this.date = date;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

 

매퍼를 만들어 준다

 

xml 매퍼

 

1) 자동매핑 

 <select id="selectCommentList3" resultType="MyComment3">
	 select comment_no "no", comment_id "id", user_name "name", comment_content "content"
	 	,comment_date "date" from mycomment join myuser on comment_id=user_id order by comment_no desc
 </select>

 

2) 수동매핑

	<resultMap type="MyComment3" id="myComment3ResultMap">
		<id column="comment_no" property="no"/>
		<result column="comment_id" property="id"/>
		<result column="comment_content" property="content"/>
		<result column="comment_date" property="date"/>
		<result column="user_name" property="name"/>
	</resultMap>
	
	<select id="selectCommentList3" resultMap="myComment3ResultMap">
		select comment_no, comment_id, user_name, comment_content, comment_date 
			from mycomment join myuser on comment_id=user_id order by comment_no desc
	</select>

 

 

인터페이스 매퍼

public interface MyCommentMapper {
	List<MyComment3> selectCommentList3();
}

 

DAO

public List<MyComment3> selectCommentList3() {
	SqlSession sqlSession=getSqlSessionFactory().openSession(true);
	try {
		return sqlSession.getMapper(MyCommentMapper.class).selectCommentList3();
	} finally {
		sqlSession.close();
	}
}

DTO 클래스를 선언해보자

 

[MyCommentUser1] 클래스 선언

 

MYCOMMENT 테이블과 MYUSER 테이블의 컬럼값을 저장하기 위한 클래스
→ 1:1 관계의 테이블 조인에 대한 검색결과를 저장하기 위한 클래스

package xyz.itwill.dto;

//MYCOMMENT 테이블과 MYUSER 테이블의 컬럼값을 저장하기 위한 클래스
//=> 1:1 관계의 테이블 조인에 대한 검색결과를 저장하기 위한 클래스
public class MyCommentUser1 {
	//MYCOMMENT 테이블(게시글정보)의 컬럼값을 저장하기 위한 필드 - 검색행 1개 
	private int commentNo;
	private String commentId;
	private String commentContent;
	private String commentDate;
		
	//MYUSER 테이블(회원정보)의 컬럼값을 저장하기 위한 필드 - 검색행 1개 
	private String userId;
	private String userName;
	
	public MyCommentUser1() {
		// TODO Auto-generated constructor stub
	}

	public int getCommentNo() {
		return commentNo;
	}

	public void setCommentNo(int commentNo) {
		this.commentNo = commentNo;
	}

	public String getCommentId() {
		return commentId;
	}

	public void setCommentId(String commentId) {
		this.commentId = commentId;
	}

	public String getCommentContent() {
		return commentContent;
	}

	public void setCommentContent(String commentContent) {
		this.commentContent = commentContent;
	}

	public String getCommentDate() {
		return commentDate;
	}

	public void setCommentDate(String commentDate) {
		this.commentDate = commentDate;
	}

	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}
}

 

xml 매퍼

<select id="selectCommentUserList1" resultType="MyCommentUser1">
	select comment_no, comment_id, comment_content, comment_date, user_id, user_name
		from mycomment join myuser on comment_id=user_id order by comment_no desc
</select>

 

인터페이스 매퍼

public interface MyCommentMapper {
	List<MyCommentUser1> selectCommentUserList1();
}

 

DAO 클래스

public List<MyCommentUser1> selectCommentUserList1() {
	SqlSession sqlSession=getSqlSessionFactory().openSession(true);
	try {
		return sqlSession.getMapper(MyCommentMapper.class).selectCommentUserList1();
	} finally {
		sqlSession.close();
	}
}

 

jsp 문서로 동작 확인 

[commentUserListSelect1.jsp]

<%@page import="xyz.itwill.dao.MyCommentDAO"%>
<%@page import="xyz.itwill.dto.MyComment1"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	List<MyComment1> commentList=MyCommentDAO.getDAO().selectCommentList1();
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MYBATIS</title>
<style type="text/css">
table {
	border: 1px solid black;
	border-collapse: collapse;
}

td {
	border: 1px solid black;
	text-align: center;
	padding: 3px;
}

.no { width: 100px; }
.name { width: 150px; }
.content { width: 250px; }
.date { width: 200px; }
</style>
</head>
<body>
	<h1>게시글 목록</h1>
	<hr>
	<table>
		<tr>
			<td class="no">게시글번호</td>
			<td class="name">게시글작성자</td>
			<td class="content">게시글내용</td>
			<td class="date">게시글작성일</td>
		</tr>
		<% for(MyComment1 comment : commentList) { %>
		<tr>
			<td><%=comment.getCommentNo() %></td>
			<td><%=comment.getCommentId() %></td>
			<td><%=comment.getCommentContent() %></td>
			<td><%=comment.getCommentDate() %></td>
		</tr>
		<% } %>
	</table>
</body>
</html>


 

association 엘리먼트로 포함관계를 이용해 DTO 클래스 작성하기

 

위의 예제를 조금 더 쉽게 만들어주는 방법이 있다.

 

포함관계를 이용해 클래스를 작성하는 것이다. (기존의 선언된 클래스를 재사용하여 새로운 클래스를 작성하는 것이다.) 

이렇게 하면 생산성 및 유지보수의 효율성이 증가한다.

 

 

DTO 선언 

 

MYCOMMENT 테이블과 MYUSER 테이블의 컬럼값을 저장하기 위한 클래스
→ 1:1 관계의 테이블 조인에 대한 검색결과를 저장하기 위한 클래스

 

필드에 반드시 객체를 저장해야지만 포함관계가 성립되기 때문에 자동매핑은 불가능하다. 

검색행을 객체로 제공받아 필드에 저장하기 위해서 반드시 수동 매핑을 이용해야 한다.

 

package xyz.itwill.dto;

public class MyCommentUser2 {
	//MYCOMMENT 테이블(게시글정보)의 검색행을 객체로 제공받아 저장하기 위한 필드 - 검색행 1개 
	private MyComment1 comment;
			
	//MYUSER 테이블(회원정보)의 검색행을 객체로 제공받아 저장하기 위한 필드 - 검색행 1개 
	private MyUser user;
	
	public MyCommentUser2() {
		// TODO Auto-generated constructor stub
	}

	public MyComment1 getComment() {
		return comment;
	}

	public void setComment(MyComment1 comment) {
		this.comment = comment;
	}

	public MyUser getUser() {
		return user;
	}

	public void setUser(MyUser user) {
		this.user = user;
	}
	
	
}

 

 

xml 매퍼 

 

association : 1:1 관계의 테이블 조인에서 1개의 검색행을 Java 객체로 생성하여 type 속성값으로 설정된 클래스의 필드에 저장되도록 매핑 처리하는 엘리먼트

id 엘리먼트 또는 result 엘리먼트를 하위 엘리먼트로 사용하여 association 엘리먼트로 생성될 객체의 필드에 검색행의 컬럼값이 저장되도록 매핑 처리한다.

 

 - property 속성 : 객체가 저장된 클래스의 필드명을 속성값으로 설정한다.

    → 객체가 저장된 클래스의 필드명을 속성값으로 설정

 - javaType 속성 : 검색행을 이용하여 생성될 객체의 Java 자료형을 속성값으로 설정한다. 

    → Java 자료형 대신 typeAlias로 설정된 별칭 사용이 가능하다.

 

검색행의 컬럼값들을 이용해 객체를 생성하여 필드에 저장하는 것이 association이다.

<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_anme" property="userName"/>
	</association>
</resultMap>
	
<select id="selectCommentUserList2" resultMap="myCommentUser2ResultMap">
	select comment_no, comment_id, comment_content, comment_date, user_id, user_name
		from mycomment join myuser on comment_id=user_id order by comment_no desc
</select>

 

인터페이스 매퍼

public interface MyCommentMapper {
	//...
   	//...
	List<MyCommentUser2> selectCommentUserList2();
}

 

DAO 

public List<MyCommentUser2> selectCommentUserList2() {
	SqlSession sqlSession=getSqlSessionFactory().openSession(true);
	try {
		return sqlSession.getMapper(MyCommentMapper.class).selectCommentUserList2();
	} finally {
		sqlSession.close();
	}
}

 

jsp

<%@page import="xyz.itwill.dao.MyCommentDAO"%>
<%@page import="xyz.itwill.dto.MyCommentUser2"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	List<MyCommentUser2> commentUserList=MyCommentDAO.getDAO().selectCommentUserList2();
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MYBATIS</title>
<style type="text/css">
table {
	border: 1px solid black;
	border-collapse: collapse;
}

td {
	border: 1px solid black;
	text-align: center;
	padding: 3px;
}

.no { width: 100px; }
.name { width: 150px; }
.content { width: 250px; }
.date { width: 200px; }
</style>
</head>
<body>
	<h1>게시글 목록</h1>
	<hr>
	<table>
		<tr>
			<td class="no">게시글번호</td>
			<td class="name">게시글작성자</td>
			<td class="content">게시글내용</td>
			<td class="date">게시글작성일</td>
		</tr>
		<% for(MyCommentUser2 commentUser : commentUserList) { %>
		<tr>
			<td><%=commentUser.getComment().getCommentNo() %></td>
			<%-- <td><%=commentUser.getUser().getUserName()%>[<%=commentUser.getComment().getCommentId() %>]</td> --%>
			<td><%=commentUser.getUser().getUserName()%>[<%=commentUser.getUser().getUserId() %>]</td>
			<td><%=commentUser.getComment().getCommentContent() %></td>
			<td><%=commentUser.getComment().getCommentDate() %></td>
		</tr>
		<% } %>
	</table>
</body>
</html>