MyBatis XML파일 다중조인

최주영·2023년 7월 9일
0

MyBatis

목록 보기
7/8
  • 문제 : BOARD , BOARD_COMMENT, MEMBER -> 3가지의 테이블을 조인시켜서
    ✅ 데이터를 하나의 객체로 출력할 수 있다
    ✅ 게시물을 조회할 때, 쿼리스트링으로 게시물번호를 넘겨줘서 하나의 게시물을 조회할것이다
    ex) <a href="${pageContext.request.contextPath}/board.do?no=21">게시글가져오기</a>

Vo 클래스

  • 결국 최종적으로 Board 안에 여러개의 테이블의 값들이 들어있다
// Board 클래스
public class Board {
	private int boardNo;
	private String boardTitle;
	private Member boardWriter;  
    // 게시글작성자는 곧 Member객체의 user이기때문에 반환형을 Member로 둔다
    // 하나의 Board에 하나의 멤버가 나옴
	private String boardContent;
	private String boardOriginalFilename;
	private String boardRenamedFilename;
	private Date boardDate;
	private int boardReadCount;
	/* private Member member; */
	private List<BoardComment> comments; 
    // 게시물 관점에서 댓글은 1:n이므로 리스트로 댓글클래스 반환
    // 하나의 Board에 여러개의 댓글이 나옴
}

// BoardComment 클래스
public class BoardComment {
	private int boardCommentNo;
	private int boardCommentLevel;
	private String boardCommentWriter;
	private String boardCommentContent;
	private int boardRef;
	private int boardCommentRef;
	private Date boardCommentDate;
}

// Member 클래스
public class Member {
	private String userId;
	private String password;
	private String userName;
	private String gender;
	private int age;
	private String email;
	private String phone;
	private String address;
	private String[] hobby;
	private Date enrollDate;
}

servlet

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String no = request.getParameter("no"); 
		service=new EmpServiceImpl(); 
		
		Board board = service.selectBoard(no); // 쿼리스트링으로 받은 no값을 인수로 service에 넘김
		
		request.setAttribute("board",board); // jsp에서 사용할 board 객체 넘겨줌

		request.getRequestDispatcher("/views/board.jsp").forward(request, response);
	}

service

  • 이전에 올렸었던 다중의 접속환경을 만들었을 때 경우
  • 본인이 사용할 접속환경의 세션 메소드를 호출한다
	@Override
	public Board selectBoard(String no){
		SqlSession session = SessionTemplate.getWebSession(); // web에 있는 세션에 접속해야함
		Board b = dao.selectBoard(session,no);
		session.close();
		return b;
	}

Dao

  • 하나의 객체만 리턴받기 때문에 selectOne 메소드를 사용한다
	@Override
	public Board selectBoard(SqlSession session, String no){
		return session.selectOne("member.selectBoard",no);
	}

mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Maper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="member">

  	<resultMap id="boardMap" type="com.employee.model.vo.Board"> <!-- type을 config.xml파일에서 별명으로 만들었음 -->
			<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"/>
			 <association property="boardWriter" resultMap="memberMap"/> 
      	<!-- 1:1 관계일때는 association 태그를 사용, Member 객체를 연결시켜줌 -->
			<collection property="comments" resultMap="boardCommentMap"/>  
      <!-- 1대N 관계일때는 collection 태그를 사용, boardComment 객체를 연결시켜줌 -->
	</resultMap>
		
	<resultMap id="boardCommentMap" type="com.employee.model.vo.BoardComment">  
			<id property="boardCommentNo" column="board_comment_no"/>
			<result property="boardCommentLevel" column="board_comment_level"/>
			<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"/>
			<result property="boardCommentWriter" column="board_comment_writer"/>  <!-- 1:1관계에서는 association 태그 사용 -->
	</resultMap>
   	
   	
  	<resultMap id="memberMap" type="com.employee.model.vo.Member">
  			<id property="userId" column="userid"/>
			<result property="password" column="password"/>
			<result property="userName" column="username"/>
			<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="hobby" column="hobby" typeHandler="strArrType"/> <!-- 타입핸들러 별칭으로 생성 -->
			<result property="enrollDate" column="enrolldate"/>	
  	</resultMap> 
  	
  
  <select id="selectBoard" resultMap="boardMap" parameterType="string">
  		SELECT * FROM BOARD 
  			LEFT JOIN BOARD_COMMENT ON BOARD_NO=BOARD_REF <!-- 댓글테이블을 불러오기위해 조인 -->
  			JOIN MEMBER ON USERID=BOARD_WRITER <!-- 게시글 작성자에 대한 멤버정보를 불러오기위해 조인 --> 
  			JOIN MEMBER M ON BOARD_COMMENT_WRITER=M.USERID <!-- 댓글작성자에 대한 멤버정보를 불러오기위해 조인 --> 
  		WHERE BOARD_NO=#{no}
  		<!-- 댓글은 없을수도있으므로 LEFTJOIN으로하고 MEMBER는 없을수가없으니까 그냥 JOIN가능함 -->
  </select>
</mapper>

jsp

<c:if test="${not empty board}">
			<table>
				<tr>
					<th>작성자 이름</th>
					<th>작성자 이메일</th>
					<th>게시글에 대한 댓글</th>
				</tr>
	
				<tr>
					<td>${board.boardWriter.userName }</td>
					<td>${board.boardWriter.email}</td>
					<td>
						<c:forEach var="bbc" items="${board.comments}">
							<ul>
								<li>${bbc.boardCommentContent}</li>
							</ul>
						</c:forEach>
					</td>
				</tr>		
			</table>
	</c:if>
profile
우측 상단 햇님모양 클릭하셔서 무조건 야간모드로 봐주세요!!

0개의 댓글