MYREPLY 테이블과 MYUSER 테이블을 조인해보자
[MYREPLY 테이블]
[MYUSER 테이블]
DTO 클래스
MYREPLY 테이블과 MYUSER 테이블의 컬럼값을 저장하기 위한 클래스
→ 1:1 관계의 테이블 조인에 대한 검색결과 저장
[MyReplyUser]
package xyz.itwill.dto;
public class MyReplyUser {
//MYREPLY 테이블(댓글정보)의 검색행을 객체로 제공받아 저장하기 위한 필드 - 검색행 1개
private MyReply reply;
//MYUSER 테이블(회원정보)의 검색행을 객체로 제공받아 저장하기 위한 필드 - 검색행 1개
private MyUser user;
public MyReplyUser() {
// TODO Auto-generated constructor stub
}
public MyReply getReply() {
return reply;
}
public void setReply(MyReply reply) {
this.reply = reply;
}
public MyUser getUser() {
return user;
}
public void setUser(MyUser user) {
this.user = user;
}
}
이렇게 기존의 클래스를 재사용하면 새로운 클래스를 쉽게 만들 수 있고, 유지보수에도 좋다.
xml 매퍼에서 select를 등록해주자
<resultMap type="MyReplyUser" id="myReplyUserResultMap1">
<association property="reply" javaType="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"/>
</association>
<association property="user" javaType="MyUser">
<id column="user_id" property="userId"/>
<result column="user_name" property="userName"/>
</association>
</resultMap>
<select id="selectReplyUserList1" resultMap="myReplyUserResultMap1">
select reply_no, reply_id, reply_content, reply_date, reply_comment_no, user_id
, user_name from myreply join myuser on reply_id=user_id order by reply_no desc
</select>
인터페이스 매퍼
public interface MyReplyMapper {
//...
//...
List<MyReplyUser> selectReplyUserList1();
}
DAO에 메소드 추가
public List<MyReplyUser> selectReplyUserList1() {
SqlSession sqlSession=getSqlSessionFactory().openSession(true);
try {
return sqlSession.getMapper(MyReplyMapper.class).selectReplyUserList1();
} finally {
sqlSession.close();
}
}
jsp 작성해 목록 확인
[replyUserListSelect1.jsp]
<%@page import="xyz.itwill.dao.MyReplyDAO"%>
<%@page import="xyz.itwill.dto.MyReplyUser"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
List<MyReplyUser> replyUserList=MyReplyDAO.getDAO().selectReplyUserList1();
%>
<!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: 300px; }
.date { width: 200px; }
.comment { width: 100px; }
</style>
</head>
<body>
<h1>댓글목록</h1>
<hr>
<table>
<tr>
<td class="no">댓글번호</td>
<td class="name">댓글작성자</td>
<td class="content">댓글내용</td>
<td class="date">댓글작성일</td>
<td class="comment">게시글번호</td>
</tr>
<% for(MyReplyUser replyUser : replyUserList) { %>
<tr>
<td><%=replyUser.getReply().getReplyNo() %></td>
<td><%=replyUser.getUser().getUserName() %>[<%=replyUser.getReply().getReplyId() %>]</td>
<td><%=replyUser.getReply().getReplyContent() %></td>
<td><%=replyUser.getReply().getReplyDate() %></td>
<td><%=replyUser.getReply().getReplyCommentNo() %></td>
</tr>
<% } %>
</table>
</body>
</html>
association 엘리먼트의 속성
association 엘리먼트에 대해 더 알아보자
resultMap 속성 : resultMap 엘리먼트의 식별자를 속성값으로 설정한다.
→ 다른 resultMap 엘리먼트의 매핑정보를 이용하여 검색행의 컬럼값이 저장된 객체를 제공받아 필드에 저장한다.
이처럼 resultMap 엘리먼트의 매핑 정보를 재사용할 수 있다.
<resultMap type="MyReply" id="myReplyResultMap">
<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 type="MyReplyUser" id="myReplyResultMap2">
<association property="reply" resultMap="myReplyResultMap"/>
</resultMap>
select 속성 : select 엘리먼트의 식별자를 속성값으로 설정한다.
→ select 엘리먼트로 검색행의 컬럼값이 저장된 객체를 제공받아 필드에 저장한다.
column 속성 : SELECT 명령에 전달될 값이 저장된 검색행의 컬럼명을 속성값으로 설정한다.
→ 검색행의 컬럼값을 select 속성값으로 설정된 select 엘리먼트의 prameterType 속성값으로 전달하여 SQL 명령에서 사용할 수 있다.
DAO 클래스의 메소드에서 사용하지 않고 association 엘리먼트에서만 사용하기 위한 SELECT 명령이기 때문에 인터페이스 기반의 매퍼 파일에서 추상메소드로 선언하지 않아도 된다.
parameterType 속성값으로 전달받은 값을 사용하여 단일행이 검색되도록 SELECT 명령을 작성해준다.
<resultMap type="MyReplyUser" id="myReplyUserResultMap2">
<association property="user" select="selectMyUser" column="reply_id"/>
</resultMap>
<!-- DAO 클래스의 메소드에서 사용하지 않고 association 엘리먼트에서만 사용하기 위한 SELECT 명령 -->
<!-- => Interface 기반의 매퍼 파일에서 추상메소드로 선언하지 않음 -->
<!-- => parameterType 속성값으로 전달받은 값을 사용하여 단일행이 검색되도록 SELECT 명령 작성 -->
<select id="selectMyUser" resultType="MyUser" parameterType="string">
select user_id, user_name from myuser where user_id=#{userId}
</select>
<!-- 테이블 조인 명령을 사용하지 않고 resultMap 엘리먼트의 매핑정보를 이용하여 2개
이상의 테이블에 대한 검색결과를 객체로 제공받아 사용 가능 -->
<select id="selectReplyUserList2" resultMap="myReplyUserResultMap2">
select reply_no, reply_id, reply_content, reply_date, reply_comment_no from myreply order by reply_no desc
</select>
이 속성을 사용하면 테이블 조인 명령을 사용하지 않아도 된다는 장점이 있다.
jsp 문서로 댓글목록 확인해보기
[replyUserListSelect2.jsp]
<%@page import="xyz.itwill.dao.MyReplyDAO"%>
<%@page import="xyz.itwill.dto.MyReplyUser"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
List<MyReplyUser> replyUserList=MyReplyDAO.getDAO().selectReplyUserList2();
%>
<!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: 300px; }
.date { width: 200px; }
.comment { width: 100px; }
</style>
</head>
<body>
<h1>댓글목록</h1>
<hr>
<table>
<tr>
<td class="no">댓글번호</td>
<td class="name">댓글작성자</td>
<td class="content">댓글내용</td>
<td class="date">댓글작성일</td>
<td class="comment">게시글번호</td>
</tr>
<% for(MyReplyUser replyUser : replyUserList) { %>
<tr>
<td><%=replyUser.getReply().getReplyNo() %></td>
<td><%=replyUser.getUser().getUserName() %>[<%=replyUser.getReply().getReplyId() %>]</td>
<td><%=replyUser.getReply().getReplyContent() %></td>
<td><%=replyUser.getReply().getReplyDate() %></td>
<td><%=replyUser.getReply().getReplyCommentNo() %></td>
</tr>
<% } %>
</table>
</body>
</html>
commentUserListSelect2.jsp 를 이용해서 게시글을 출력해보자
[MYCOMMENT] 테이블
DTO 클래스를 만들어준다
MYCOMMENT 테이블과 MYREPLY 테이블의 컬럼값을 저장하기 위한 클래스
=> 1:N 관계의 테이블 조인에 대한 검색결과를 저장할 목적의 클래스
[MyCommentReply]
package xyz.itwill.dto;
import java.util.List;
public class MyCommentReply {
//MYCOMMENT 테이블(게시글정보)의 검색행을 객체로 제공받아 저장하기 위한 필드 - 검색행 1개
private MyComment1 comment;
//MYREPLY 테이블(댓글정보)의 검색행을 객체로 제공받아 저장하기 위한 필드 - 검색행 0개 이상
private List<MyReply> replyList;
public MyCommentReply() {
// TODO Auto-generated constructor stub
}
public MyComment1 getComment() {
return comment;
}
public void setComment(MyComment1 comment) {
this.comment = comment;
}
public List<MyReply> getReplyList() {
return replyList;
}
public void setReplyList(List<MyReply> replyList) {
this.replyList = replyList;
}
}
xml 기반의 매퍼파일 만들기
먼저 조인을 하지 않고 만들어 보자.
[MyCommentMapper.xml]
게시글번호를 전달받아 MYCOMMENT 테이블에 저장된 게시글정보를 검색하여 MyComment1 객체로 제공하는 엘리먼트를 선언한다. (검색행은 1개이다)
<select id="selectComment" parameterType="int" resultType="MyComment1">
select comment_no, comment_id, comment_content, comment_date from mycomment where comment_no=#{commentNo}
</select>
게시글번호를 전달받아 MYREPLY 테이블에 저장된 댓글정보를 검색하여 MyReply 객체로 제공하는 엘리먼트를 선언한다. (검색행은 0개 이상이다)
<select id="selectCommentNoReplyList" parameterType="int" resultType="MyReply">
select reply_no, reply_id, reply_content, reply_date, reply_comment_no
from myreply where reply_comment_no=#{replyCommentNo} order by reply_no desc
</select>
인터페이스 매퍼파일
[MyCommentMapper]
public interface MyCommentMapper {
//...
//...
MyComment1 selectComment(int commentNo);
List<MyReply> selectCommentNoReplyList(int commentNo);
}
DAO
[MyCommentDAO]
public MyComment1 selectComment(int commentNo) {
SqlSession sqlSession=getSqlSessionFactory().openSession(true);
try {
return sqlSession.getMapper(MyCommentMapper.class).selectComment(commentNo);
} finally {
sqlSession.close();
}
}
public List<MyReply> selectCommentNoReplyList(int commentNo) {
SqlSession sqlSession=getSqlSessionFactory().openSession(true);
try {
return sqlSession.getMapper(MyCommentMapper.class).selectCommentNoReplyList(commentNo);
} finally {
sqlSession.close();
}
}
jsp문서 연결
[commentUserListSelect2.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>
<a href="commentReplySelect1.jsp?commentNo=<%=commentUser.getComment().getCommentNo()%>">
<%=commentUser.getComment().getCommentContent() %>
</a>
</td>
<td><%=commentUser.getComment().getCommentDate() %></td>
</tr>
<% } %>
</table>
</body>
</html>
[commentReplySelect1.jsp]
<%@page import="xyz.itwill.dto.MyReply"%>
<%@page import="java.util.List"%>
<%@page import="xyz.itwill.dao.MyCommentDAO"%>
<%@page import="xyz.itwill.dto.MyComment1"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
if(request.getParameter("commentNo")==null) {//전달값(게시글번호)이 없는 경우
//게시글목록을 출력하는 페이지로 이동
response.sendRedirect("commentUserListSelect2.jsp");
return;
}
//전달값(게시글번호)을 반환받아 저장
int commentNo=Integer.parseInt(request.getParameter("commentNo"));
//게시글번호를 이용하여 MYCOMMENT 테이블에 저장된 게시글을 검색하여 DTO 객체로 반환하는 DAO 클래스의 메소드 호출
MyComment1 comment=MyCommentDAO.getDAO().selectComment(commentNo);
//게시글번호를 이용하여 MYREPLY 테이블에 저장된 댓글목록을 검색하여 List 객체로 반환하는 DAO 클래스의 메소드 호출
List<MyReply> replyList=MyCommentDAO.getDAO().selectCommentNoReplyList(commentNo);
%>
<!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: 300px; }
.date { width: 200px; }
.comment { width: 100px; }
</style>
</head>
<body>
<h1>게시글과 댓글목록</h1>
<hr>
<%-- 게시글 출력 --%>
<table>
<tr>
<td width="200">게시글번호</td>
<td width="300"><%=comment.getCommentNo() %></td>
</tr>
<tr>
<td width="200">게시글작성자</td>
<td width="300"><%=comment.getCommentId() %></td>
</tr>
<tr>
<td width="200">게시글내용</td>
<td width="300"><%=comment.getCommentContent() %></td>
</tr>
<tr>
<td width="200">게시글작성일</td>
<td width="300"><%=comment.getCommentDate() %></td>
</tr>
</table>
<br>
<%-- 댓글목록 출력 --%>
<table>
<tr>
<td class="no">댓글번호</td>
<td class="name">댓글작성자</td>
<td class="content">댓글내용</td>
<td class="date">댓글작성일</td>
<td class="comment">게시글번호</td>
</tr>
<% if(replyList.isEmpty()) { %>
<tr>
<td colspan="5">댓글이 존재하지 않습니다.</td>
</tr>
<% } else { %>
<% for(MyReply reply : replyList) { %>
<tr>
<td><%=reply.getReplyNo() %></td>
<td><%=reply.getReplyId() %></td>
<td><%=reply.getReplyContent() %></td>
<td><%=reply.getReplyDate() %></td>
<td><%=reply.getReplyCommentNo() %></td>
</tr>
<% } %>
<% } %>
</table>
</body>
</html>
'학원 > 복기' 카테고리의 다른 글
[Mybatis] discriminator 엘리먼트 (0) | 2023.07.21 |
---|---|
[MyBatis] 조인예제(3) / collection 엘리먼트, autoMapping 속성 (0) | 2023.07.21 |
[MyBatis] 비교연산자가 엘리먼트로 인식되는 에러 해결 (0) | 2023.07.21 |
[MyBatis] 조인예제(1) / association 엘리먼트 (0) | 2023.07.21 |
[MyBatis] 자동매핑&수동매핑 예제 / selectKey,counstructor 엘리먼트 (0) | 2023.07.19 |