MyBatis 게시글 답글

woom·2023년 2월 1일
0

Framework

목록 보기
2/20
post-thumbnail

🌼 게시글 작성

  • MYCOMMENT 테이블 : 게시글을 저장하기 위한 테이블 생성
create table mycomment(comment_no number primary key, comment_id varchar2(50)
    , comment_content varchar2(100), comment_date date);
  • MYCOMMENT_SEQ : MYCOMMENT 테이블의 COMMENT_NO 컬럼에 저장될 자동 증가값을 제공하기 위한 시퀸스
    create sequence mycomment_seq;
이름              널?       유형            
--------------- -------- ------------- 
COMMENT_NO      NOT NULL NUMBER        - 게시글 번호
COMMENT_ID               VARCHAR2(50)  - 게시글 작성자(아이디)
COMMENT_CONTENT          VARCHAR2(100) - 게시글 내용 
COMMENT_DATE             DATE          - 게시글 작성일

📕 DTO class (컬럼명=필드명)

  • mybatis 환경설정 파일(mybatis-config.xml)의 setting 엘리먼트를 사용하여 스네이크 표기법으로 표현된 식별자를 자동으로 카멜 표기법으로 변환되도록 환경설정 변경
  • 테이블의 컬럼명을 같은 이름의 필드로 선언하여 클래스 작성 (환경설정 파일에 의해 컬럼명과 필드명 동일)

  • XML 기반의 매퍼 파일에서 cache 엘리먼트를 사용한 경우 SELECT 명령에 대한 검색결과로 제공될 객체의 클래스는 반드시 객체 직렬화 클래스로 선언

    • 객체 직렬화 클래스는 Serializable 인터페이스를 상속받아 작성
    • 객체 직렬화 클래스는 serialVersionUID 이름의 static final 필드 선언하는 것을 권장

package xyz.itwill.dto;

import java.io.Serializable;

public class MyComment1 implements Serializable {
	private static final long serialVersionUID = -7534009978055893003L;

	private int commentNo;
	private String commentId;
	private String commentContent;
	private String commentDate;
	
	public MyComment1() {
		// 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;
	}
}





📕 DTO class (컬럼명!=필드명)

  • 테이블의 컬럼명과 다른 이름의 필드를 선언하여 클래스 작성

  • 매개변수가 작성된 생성자를 생성(필드 생성자 초기화 → 매개변수로 초기값 설정)하여 XML 매퍼파일에서 매핑 시 사용 가능


package xyz.itwill.dto;

public class MyComment2 {
	private int no;
	private String id;
	private String content;
	private String date;
	
	public MyComment2() {
		// TODO Auto-generated constructor stub
	}

	public MyComment2(int no, String id) {
		super();
		this.no = no;
		this.id = id;
	}

	public MyComment2(int no, String id, String content, String date) {
		super();
		this.no = no;
		this.id = id;
		this.content = content;
		this.date = date;
	}

	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;
	}
}





📕 DTO class (join id)

  • MYCOMMENT 테이블과 MYUSER 테이블의 검색결과를 저장하기 위한 클래스
    • 1:1 관계의 조인 검색 결과를 저장하기 위한 클래스
package xyz.itwill.dto;

public class MyComment3 {
	private int no;
	private String id;
	private String name;
	private String content;
	private String date;
	
	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 getName() {
		return name;
	}

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

	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;
	}
}





📕 DTO class (필드로 값 저장)

  • MYCOMMENT 테이블과 MYUSER 테이블의 검색결과를 저장하기 위한 클래스

    • 1:1 관계의 조인 검색 결과를 저장하기 위한 클래스
package xyz.itwill.dto;

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;
	}
}





📕 DTO class (클래스 재사용)

  • MYCOMMENT 테이블과 MYUSER 테이블의 검색결과를 저장하기 위한 클래스

    • 1:1 관계의 조인 검색 결과를 저장하기 위한 클래스
    • 기존에 선언된 클래스(POJO : Plan Old Java Object)를 재사용하여 새로운 클래스 작성
    • 생산성 증가 및 유지보수의 효율성 증가
  • MYCOMMENT 테이블(게시글정보)의 검색결과를 저장하기 위한 필드

    • 객체를 저장하기 위한 필드 : 포함관계
    • 포함관계가 성립되기 위해서는 반드시 필드에 객체 저장
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 매퍼 (comment)

  • cache : SELECT 명령의 검색결과를 임시 메모리(Cache Memory)에 저장하여 빠른 검색결과를 제공하기 위한 엘리먼트 (가독성 증가)

    • INSERT,UPDATE,DELETE 명령이 실행되면 임시 메모리에 저장된 검색결과는 자동 초기화
    • 검색결과를 저장하는 객체는 반드시 객체 직렬화 클래스로 작성
  • selectKey : SELECT 명령의 검색 결과값을 insert 엘리먼트의 parameterType 속성값으로 설정된 클래스의 필드값으로 저장하기 위한 엘리먼트

    • insert 엘리먼트에 종속된 엘리먼트 (필요 시 재사용 가능)
    • 자동 증가값 또는 난수값을 SELECT 명령으로 검색하여 객체의 필드에 저장 후 INSERT 명령에서 사용하기 위해 작성
    • resultType 속성 : SELECT 명령으로 검색된 결과값을 반환받기 위한 Java 자료형을 속성값으로 설정
    • keyProperty 속성 : insert 엘리먼트의 parameterType 속성값으로 설정된 클래스의 필드명을 속성값으로 설정
      (SELECT 명령의 검색 결과값을 제공받아 Java 객체의 필드에 저장하기 위해 설정)
    • order 속성 : BEFORE(insert 명령 실행되기 전) 또는 AFTER(후) 중 하나를 속성값으로 설정
    • <selectKey resultType="int" keyProperty="commentNo" order="BEFORE">
  1. 검색행의 컬럼명과 resultType 속성값으로 설정된 클래스의 필드명이 같도록 작성
    • resultType 속성을 사용하여 자동 매핑 기능으로 Java 객체 제공
  1. 검색행의 컬럼명과 resultType 속성값으로 설정된 클래스의 필드명이 모두 다른 경우 resultType 속성값으로 설정된 클래스의 객체 대신 NULL 제공
  • 검색행의 컬럼명을 resultType 속성값으로 설정된 클래스의 필드명과 같도록 Column Alias 기능을 사용하여 검색
    (컬럼의 별칭으로 사용하기 부적절한 단어는 "" 기호를 사용하여 표현 ex. date)
  • resultMap 엘리먼트를 이용하여 검색행의 컬럼값을 클래스의 필드에 저장되도록 설정하여 제공 (수동매핑)
    • type 속성값으로 설정된 Java 클래스의 기본 생성자로 객체를 생성하고 검색행의 컬럼값을 id 엘리먼트 또는 result 엘리먼트를 사용하여 객체의 Setter 메소드를 호출하여 필드값이 변경되도록 처리
  • constructor 엘리먼트를 사용하여 type 속성값으로 설정된 Java 클래스의 매개변수가 작성된 생성자로 객체를 생성하고 생성자 매개변수에 검색행의 컬럼값을 전달하여 객체의 필드에 저장되도록 매핑 처리
    • constructor : resultMap 엔리먼트의 type 속성값으로 설정된 Java 클래스의 생성자를 이용하여 매핑 처리하기 위한 정보를 제공하는 엘리먼트
    • 하위 엘리먼트 : idArg, arg
    • 생성자 매개변수와 하위 엘리먼트의 갯수와 자료형이 동일해야만 매핑 가능
    • idArg : 검색행의 컬럼값을 생성자 매개변수에 전달하기 위한 엘리먼트 (PK 제약조건이 설정된 컬럼값을 제공받아 생성자 매개변수에 전달하기 위해 사용)
    • column 속성 : 검색행의 컬럼명을 속성값으로 설정
    • javaType 속성 : 생성자 매개변수의 자료형을 속성값으로 설정 (Java 자료형 대신 typeAlias 엘리먼트로 설정된 별칭 사용 가능)
    • <idArg column="comment_no" javaType="_int"/>
    • comment_no의 컬럼을 전달받아 int형식의 생성자 매개변수로 전달하여 매핑처리 (초기화)
    • int의 별칭은 int (는 원시형) / Integer 클래스의 별칭은 int
    • arg : 검색행의 컬럼값을 생성자 매개변수에 전달하기 위한 엘리먼트
    • <arg column="comment_id" javaType="string"/>
    • constructor 엘리먼트와 id 엘리먼트(result 엘리먼트)를 같이 사용하여 매핑 처리 가능
  1. 1:1 관계의 join 검색 결과를 저장
  • 검색행의 컬럼명을 resultType 속성값으로 설정된 클래스의 필드명과 같도록 Column Alias 기능을 사용하여 검색 (자동매핑)
  • resultMap 엘리먼트를 이용하여 검색행의 컬럼값을 클래스의 필드에 저장되도록 설정하여 제공 (수동매핑)
  1. resultMap 엘리먼트의 type 속성값으로 설정된 클래스의 필드가 Java 객체를 저장하기 위한 필드로 선언된 경우 하위 엘리먼트로 association 엘리먼트를 사용하여 Java 객체를 제공받아 필드에 저장되도록 설정
  • association : 1:1 관계의 테이블 조인에서 1개의 검색행을 Java 객체로 제공받아 필드에 저장되도록 매핑 처리하는 엘리먼트 (포함관계 성립)
  • id 엘리먼트와 result 엘리먼트를 하위 엘리먼트로 사용하여 검색행의 컬럼값이 포함 관계의 객체의 필드에 저장되도록 설정
    • property 속성 : 포함 관계의 객체를 저장하기 위한 필드명을 속성값으로 설정
    • javaType 속성 : 검색결과를 제공받기 위한 객체의 Java 자료형을 속성값으로 설정
    • Java 자료형 대신 typeAlias 엘리먼트로 설정된 별칭 사용 가능
    • <association property="comment" javaType="MyComment1">
    • MyComment1(자료형) 객체를 제공받아 comment라는 필드에 저장
    • <id column="comment_no" property="commentNo"/>
    • id, result를 이용해서 필드에 검색 결과 저장

🐣 예제

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="xyz.itwill.mapper.MyCommentMapper">
	<insert id="insertComment1" parameterType="MyComment1">
		insert into mycomment values(mycomment_seq.nextval, #{commentId}, #{commentContent}, sysdate)
	</insert>
	
	<insert id="insertComment2" parameterType="MyComment1">
		<!-- selectKey : SELECT 명령의 검색 결과값을 insert 엘리먼트의 parameterType 속성값으로
		설정된 클래스의 필드값으로 저장하기 위한 엘리먼트 - insert 엘리먼트에 종속된 엘리먼트 -->
		<!-- => 자동 증가값 또는 난수값을 SELECT 명령으로 검색하여 객체의 필드에 저장하여 INSERT 명령에서 사용하기 위해 작성 -->
		<!-- resultType 속성 : SELECT 명령으로 검색된 결과값을 반환받기 위한 Java 자료형을 속성값으로 설정 -->
		<!-- keyProperty 속성 : insert 엘리먼트의 parameterType 속성값으로 설정된 클래스의 필드명을 속성값으로 설정 -->
		<!-- => SELECT 명령의 검색 결과값을 제공받아 Java 객체의 필드에 저장하기 위해 설정 -->
		<!-- order 속성 : BEFORE 또는 AFTER 중 하나를 속성값으로 설정 -->
		<selectKey resultType="int" keyProperty="commentNo" order="BEFORE">
			select mycomment_seq.nextval from dual
		</selectKey>
		insert into mycomment values(#{commentNo}, #{commentId}, #{commentContent}, sysdate)
	</insert>
	
	<!-- resultType 속성을 사용하여 자동 매핑 기능으로 Java 객체 제공 -->
	<!-- => 검색행의 컬럼명과 resultType 속성값으로 설정된 클래스의 필드명이 같도록 작성 -->
	<select id="selectCommentList1" resultType="MyComment1">
		select * from mycomment order by comment_no desc
	</select>
	
	<!-- 검색행의 컬럼명과 resultType 속성값으로 설정된 클래스의 필드명이 모두 다른 경우
	resultType 속성값으로 설정된 클래스의 객체 대신 NULL 제공 -->
	<!-- 
	<select id="selectCommentList2" resultType="MyComment2">
		select * from mycomment order by comment_no desc
	</select>
	-->
	
	<!-- 검색행의 컬럼명을 resultType 속성값으로 설정된 클래스의 필드명과 같도록 Column Alias
	기능을 사용하여 검색 - 컬럼의 별칭으로 사용하기 부적절한 단어는 "" 기호를 사용하여 표현 -->
	<!--  
	<select id="selectCommentList2" resultType="MyComment2">
		select comment_no no, comment_id id, comment_content content
			,comment_date "date" from mycomment order by comment_no desc
	</select>
	-->
	
	<!-- resultMap 엘리먼트를 이용하여 검색행의 컬럼값을 클래스의 필드에 저장되도록 설정하여 제공  -->
	<!-- => type 속성값으로 설정된 Java 클래스의 기본 생성자로 객체를 생성하고 검색행의	컬럼값을 
	id 엘리먼트 또는 result 엘리먼트를 사용하여 객체의 Setter 메소드를 호출하여 필드값이 변경되도록 처리 -->
	<resultMap type="MyComment2" id="myComment2ResultMap">
		<id column="comment_no" property="no"/>	
		<result column="comment_id" property="id"/>	
		<result column="comment_content" property="content"/>	
		<result column="comment_date" property="date"/>	
	</resultMap>
	
	<!-- select 엘리먼트의 resultMap 속성을 사용하여 검색행을 Java 객체로 수동 매핑하여 제공 -->
	<!--  
	<select id="selectCommentList2" resultMap="myComment2ResultMap">
		select * from mycomment order by comment_no desc
	</select>
	-->
	
	<!-- constructor 엘리먼트를 사용하여 type 속성값으로 설정된 Java 클래스의 매개변수가 
	작성된 생성자로 객체를 생성하고 생성자 매개변수에 검색행의 컬럼값을 전달하여 객체의 
	필드에 저장되도록 매핑 처리  -->
	<resultMap type="MyComment2" id="myComment2ConstructResultMap">
		<!-- constructor : resultMap 엘리먼트의 type 속성값으로 설정된 Java 클래스의 생성자를 
		이용하여 매핑 처리하기 위한 정보를 제공하는 엘리먼트 -->
		<!-- => 하위 엘리먼트 : idArg, arg -->
		<!-- => 생성자 매개변수와 하위 엘리먼트의 갯수와 자료형이 동일해야만 매핑 가능 -->
		<constructor>
			<!-- idArg : 검색행의 컬럼값을 생성자 매개변수에 전달하기 위한 엘리먼트 -->
			<!-- => PK 제약조건이 설정된 컬럼값을 제공받아 생성자 매개변수에 전달하기 위해 사용 -->
			<!-- column 속성 : 검색행의 컬럼명을 속성값으로 설정 -->
			<!-- javaType 속성 : 생성자 매개변수의 자료형을 속성값으로 설정 -->
			<!-- => Java 자료형 대신 typeAlias 엘리먼트로 설정된 별칭 사용 가능 -->
			<idArg column="comment_no" javaType="_int"/> 
			<!-- arg : 검색행의 컬럼값을 생성자 매개변수에 전달하기 위한 엘리먼트 -->
			<arg column="comment_id" javaType="string"/>
			<!-- 
			<arg column="comment_content" javaType="string"/>
			<arg column="comment_date" javaType="string"/>
			-->
		</constructor>
		<!-- constructor 엘리먼트와 id 엘리먼트(result 엘리먼트)를 같이 사용하여 매핑 처리 가능 -->
		<result column="comment_content" property="content"/>	
		<result column="comment_date" property="date"/>	
	</resultMap>
	
	<select id="selectCommentList2" resultMap="myComment2ConstructResultMap">
		select * from mycomment order by comment_no desc
	</select>
	
	<!--  
	<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>
	-->
	
	<resultMap type="MyComment3" id="myComment3ResultMap">
		<id column="comment_no" property="no"/>
		<result column="comment_id" property="id"/>
		<result column="user_name" property="name"/>
		<result column="comment_content" property="content"/>
		<result column="comment_date" property="date"/>
	</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>
	
	<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>
	
	<!-- resultMap 엘리먼트의 type 속성값으로 설정된 클래스의 필드가 Java 객체를 저장하기 위한
	필드로 선언된 경우 하위 엘리먼트로 association 엘리먼트를 사용하여 Java 객체를 제공받아
	필드에 저장되도록 설정 -->
	<resultMap type="MyCommentUser2" id="myCommentUser2ResultMap">
		<!-- association : 1:1 관계의 테이블 조인에서 1개의 검색행을 Java 객체로 제공받아
		필드에 저장되도록 매핑 처리하는 엘리먼트 - 포함관계 성립 -->
		<!-- => id 엘리먼트와 result 엘리먼트를 하위 엘리먼트로 사용하여 검색행의 컬럼값이
		포함 관계의 객체의 필드에 저장되도록 설정 -->
		<!-- property 속성 : 포함 관계의 객체를 저장하기 위한 필드명을 속성값으로 설정 -->
		<!-- javaType 속성 : 검색결과를 제공받기 위한 객체의 Java 자료형을 속성값으로 설정 -->
		<!-- => Java 자료형 대신 typeAlias 엘리먼트로 설정된 별칭 사용 가능 -->
		<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>
	
	<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>
</mapper>





📙 interface 매퍼 (comment)



package xyz.itwill.mapper;

import java.util.List;

import xyz.itwill.dto.MyComment1;
import xyz.itwill.dto.MyComment2;
import xyz.itwill.dto.MyComment3;
import xyz.itwill.dto.MyCommentUser1;
import xyz.itwill.dto.MyCommentUser2;

public interface MyCommentMapper {
	int insertComment1(MyComment1 comment);
	int insertComment2(MyComment1 comment);
	List<MyComment1> selectCommentList1();
	List<MyComment2> selectCommentList2();
	List<MyComment3> selectCommentList3();
	List<MyCommentUser1> selectCommentUserList1();
	List<MyCommentUser2> selectCommentUserList2();
}







📒 DAO class

  • insertComment1() : 게시글 등록 (로깅정보에서 comment_no값 확인 불가)
  • insertComment2() : 게시글 등록 (xml 매퍼에서 selectKey 엘리먼트를 사용하여 로깅정보에서 comment_no값 확인 가능)
  • selectCommentList1() : 게시글 목록 출력 (검색행의 컬럼명과 resultType 속성값으로 설정된 클래스의 필드명이 같을 경우)
  • selectCommentList2() : 게시글 목록 출력 (검색행의 컬럼명과 resultType 속성값으로 설정된 클래스의 필드명이 모두 다른 경우)
  • selectCommentList3() : 게시글 목록 출력 (join을 이용하여 select 문 작성)
  • selectCommentUserList1 : 게시글 목록 출력 (MYCOMMENT 테이블과 MYUSER 테이블의 모든 필드를 선언한 클래스 → 필드에 값 저장)
  • selectCommentUserList2 : 게시글 목록 출력 (기존에 선언된 클래스를 재사용하여 새로운 클래스 작성 → 객체를 생성하여 값 저장)


package xyz.itwill.dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import xyz.itwill.dto.MyComment1;
import xyz.itwill.dto.MyComment2;
import xyz.itwill.dto.MyComment3;
import xyz.itwill.dto.MyCommentUser1;
import xyz.itwill.dto.MyCommentUser2;
import xyz.itwill.mapper.MyCommentMapper;

public class MyCommentDAO extends AbstractSession {
	private static MyCommentDAO _dao;
	
	private MyCommentDAO() {
		// TODO Auto-generated constructor stub
	}
	
	static {
		_dao=new MyCommentDAO();
	}
	
	public static MyCommentDAO getDAO() {
		return _dao;
	}
	
	public int insertComment1(MyComment1 comment) {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyCommentMapper.class).insertComment1(comment);
		} finally {
			sqlSession.close();
		}
	}
	
	public int insertComment2(MyComment1 comment) {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyCommentMapper.class).insertComment2(comment);
		} finally {
			sqlSession.close();
		}
	}
	
	public List<MyComment1> selectCommentList1() {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyCommentMapper.class).selectCommentList1();
		} finally {
			sqlSession.close();
		}
	}
	
	public List<MyComment2> selectCommentList2() {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyCommentMapper.class).selectCommentList2();
		} finally {
			sqlSession.close();
		}
	}
	
	public List<MyComment3> selectCommentList3() {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyCommentMapper.class).selectCommentList3();
		} finally {
			sqlSession.close();
		}
	}
	public List<MyCommentUser1> selectCommentUserList1() {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyCommentMapper.class).selectCommentUserList1();
		} finally {
			sqlSession.close();
		}
	}
	public List<MyCommentUser2> selectCommentUserList2() {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyCommentMapper.class).selectCommentUserList2();
		} finally {
			sqlSession.close();
		}
	}
}





🐣 게시글 등록1

  • 로깅정보에서 comment_no 값 확인 불가

<%@page import="xyz.itwill.dao.MyCommentDAO"%>
<%@page import="xyz.itwill.dto.MyComment1"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	MyComment1 comment1=new MyComment1();
	comment1.setCommentId("abc");
	comment1.setCommentContent("첫번째 게시글입니다.");
	MyCommentDAO.getDAO().insertComment1(comment1);
	
	MyComment1 comment2=new MyComment1();
	comment2.setCommentId("xyz");
	comment2.setCommentContent("두번째 게시글입니다.");
	MyCommentDAO.getDAO().insertComment1(comment2);
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MYBATIS</title>
</head>
<body>
	<h1>게시글 등록</h1>
	<hr>
	<h3>게시글이 성공적으로 삽입 되었습니다.</h3>
</body>
</html>





🐣 게시글 등록2 (selectKey)

  • xml 매퍼에서 selectKey 엘리먼트를 사용하여 SELECT 명령의 검색 결과값을 insert 엘리먼트의 parameterType 속성값으로 설정된 클래스의 필드값으로 저장 가능

<%@page import="xyz.itwill.dao.MyCommentDAO"%>
<%@page import="xyz.itwill.dto.MyComment1"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	MyComment1 comment3=new MyComment1();
	comment3.setCommentId("opq");
	comment3.setCommentContent("세번째 게시글입니다.");
	MyCommentDAO.getDAO().insertComment2(comment3);
	
	MyComment1 comment4=new MyComment1();
	comment4.setCommentId("abc");
	comment4.setCommentContent("네번째 게시글입니다.");
	MyCommentDAO.getDAO().insertComment2(comment4);
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MYBATIS</title>
</head>
<body>
	<h1>게시글 등록</h1>
	<hr>
	<h3>게시글이 성공적으로 삽입 되었습니다.</h3>
</body>
</html>





🐣 게시글 목록1 (컬럼명=필드명)

<%@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>





🐣 게시글 목록2 (컬럼명!=필드명)

<%@page import="xyz.itwill.dto.MyComment2"%>
<%@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<MyComment2> commentList=MyCommentDAO.getDAO().selectCommentList2();
%>    
<!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(MyComment2 comment:commentList) { %>
		<tr>
			<td><%=comment.getNo() %></td>
			<td><%=comment.getId() %></td>
			<td><%=comment.getContent() %></td>
			<td><%=comment.getDate() %></td>
		</tr>
		<% } %>
	</table>	
</body>
</html>





🐣 게시글 목록3 (join)

<%@page import="xyz.itwill.dto.MyComment3"%>
<%@page import="xyz.itwill.dto.MyComment2"%>
<%@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<MyComment3> commentList=MyCommentDAO.getDAO().selectCommentList3();
%>    
<!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(MyComment3 comment:commentList) { %>
		<tr>
			<td><%=comment.getNo() %></td>
			<td><%=comment.getName() %>(<%=comment.getId() %>)</td>
			<td><%=comment.getContent() %></td>
			<td><%=comment.getDate() %></td>
		</tr>
		<% } %>
	</table>	
</body>
</html>





🐣 게시글 목록4 (필드에 값 저장)

  • MYCOMMENT 테이블과 MYUSER 테이블의 모든 필드를 선언한 클래스를 이용하여 필드에 값 저장
<%@page import="xyz.itwill.dao.MyCommentDAO"%>
<%@page import="xyz.itwill.dto.MyCommentUser1"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	List<MyCommentUser1> commentUserList=MyCommentDAO.getDAO().selectCommentUserList1();
%>    
<!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(MyCommentUser1 commentUser:commentUserList) { %>
		<tr>
			<td><%=commentUser.getCommentNo() %></td>
			<%-- <td><%=commentUser.getUserName() %>(<%=commentUser.getCommentId() %>)</td> --%>
			<td><%=commentUser.getUserName() %>(<%=commentUser.getUserId() %>)</td>
			<td><%=commentUser.getCommentContent() %></td>
			<td><%=commentUser.getCommentDate() %></td>
		</tr>
		<% } %>
	</table>	
</body>
</html>




🐣 게시글 목록5 (객체를 생성하여 값 저장)

  • 기존에 선언된 클래스를 재사용하여 새로운 클래스 작성 → 객체를 생성하여 값 저장

<%@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>





🌼 게시글에 대한 댓글 저장

  • MYREPLY 테이블 : 게시글에 대한 댓글을 저장하기 위한 테이블
create table myreply(reply_no number primary key, reply_id varchar2(50)
    ,reply_content varchar2(100),reply_date date,reply_comment_no number);
    
  • MYREPLY_SEQ : MYREPLY 테이블의 REPLY_NO 컬럼에 저장될 자동 증가값을 제공하기 위한 시퀸스
    • create sequence myreply_seq;

이름               널?       유형            
---------------- -------- ------------- 
REPLY_NO         NOT NULL NUMBER        - 댓글 번호
REPLY_ID                  VARCHAR2(50)  - 댓글 작성자(아이디)
REPLY_CONTENT             VARCHAR2(100) - 댓글 내용 
REPLY_DATE                DATE          - 댓글 작성일
REPLY_COMMENT_NO          NUMBER        - 게시글 번호 

📕 DTO class (reply)

package xyz.itwill.dto;

public class MyReply {
	private int replyNo;
	private String replyId;
	private String replyContent;
	private String replyDate;
	private int replyCommentNo;
	
	public MyReply() {
		// TODO Auto-generated constructor stub
	}

	public int getReplyNo() {
		return replyNo;
	}

	public void setReplyNo(int replyNo) {
		this.replyNo = replyNo;
	}

	public String getReplyId() {
		return replyId;
	}

	public void setReplyId(String replyId) {
		this.replyId = replyId;
	}

	public String getReplyContent() {
		return replyContent;
	}

	public void setReplyContent(String replyContent) {
		this.replyContent = replyContent;
	}

	public String getReplyDate() {
		return replyDate;
	}

	public void setReplyDate(String replyDate) {
		this.replyDate = replyDate;
	}

	public int getReplyCommentNo() {
		return replyCommentNo;
	}

	public void setReplyCommentNo(int replyCommentNo) {
		this.replyCommentNo = replyCommentNo;
	}
}





⭐ xml 매퍼 (MYREPLY)

  1. MYREPLY 테이블에 저장된 모든 댓글 검색
  1. MYREPLY 테이블에 저장된 모든 댓글중에서 가장 최근에 작성된 5개의 댓글만 검색
  • 문제점 : XML 기반의 매퍼 파일에서는 SQL 명령이 등록된 엘리먼트에서 관계 연산자 ( > 또는 < )를 사용할 경우 엘리먼트를 표시하는 기호로 인식되어 에러 발생
  • 해결법1 : 관계 연산자 ( > 또는 < )를 엔티티 레퍼런스(회피문자)로 변경하여 SQL 명령 작성
  • select rownum, reply.* from (select * from myreply order by reply_no desc) reply where rownum &lt;= 5
  • 해결법2 : CDATA 세션을 사용하여 SQL 명령 작성
  1. join을 사용한 select 문
  • resultMap 엘리먼트의 type 속성값으로 설정된 클래스의 필드가 Java 객체를 저장하기 위한 필드로 선언된 경우 하위 엘리먼트로 association 엘리먼트를 사용하여 Java 객체를 제공받아 필드에 저장되도록 설정

    • table join하여 검색
  1. 테이블 조인을 사용하지 않고 resultMap 엘리먼트의 매핑정보를 제공받아 2개 이상의 테이블의 컬럼값을 검색하여 Java 객체로 제공 가능
  • resultMap 엘리먼트의 하위 엘리먼트인 association 엘리먼트의 reultMap, select 속성

    • reultMap 속성 : reultMap 엘리먼트의 식별자를 속성값을 설정
    • reultMap 엘리먼트로 설정된 매핑정보를 이용하여 검색행의 컬럼값을 객체 필드에 저장하여 객체를 제공받아 포함 객체의 필드에 저장
    • <association property="reply" resultMap="myReplyResultMap"/>
    • myReplyResultMap을 식별자로 같은 MyReply 객체의 컬럼값이 저장된 객체를 제공받아 reply 필드에 저장
  • select 속성 : select 엘리먼트의 식별자를 속성값으로 설정

    • select 엘리먼트의 SELECT 명령으로 실행된 검색결과를 객체로 제공받아 포함 객체 필드에 저장
  • column 속성 : SELECT 명령으로 검색된 행의 컬럼명을 속성값으로 설정

    • SELECT 명령으로 검색된 행의 컬럼값을 select 속성값으로 설정된 select 엘리먼트의 parameterType 속성값으로 전달하여 SQL 명령에서 사용
  • association 엘리먼트에서만 사용하기 위한 SELECT 명령 등록

    • parameterType 속성으로 전달받은 값으로 단일행이 검색되도록 SELECT 명령 작성
    • DAO 클래스의 메소드에서 사용될 SQL 명령이 아니므로 Interface 기반의 맵퍼 파일에서 추상메소드 미선언
  • select문에서 검색된 행의 컬럼값과 매핑된 클래스(MyReplyUser)의 필드로 reply와 user가 저장됨

    • reply : MyReply객체를 생성하여 필드값을 변경하는 myReplyResultMap을 포함 객체 필드(reply)에 저장
    • user : 컬럼명이 reply_id와 같은 자료형인 myuser객체 생성 후 검색된 값을 user에 저장

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="xyz.itwill.mapper.MyReplyMapper">
	<insert id="insertReply" parameterType="MyReply">
		<selectKey resultType="int" keyProperty="replyNo" order="BEFORE">
			select myreply_seq.nextval from dual
		</selectKey>
		insert into myreply values(#{replyNo},#{replyId},#{replyContent},sysdate,#{replyCommentNo})
	</insert>
	
	<select id="selectReplyList" resultType="MyReply">
		select * from myreply order by reply_no desc
	</select>
	
	<!-- MYREPLY 테이블에 저장된 모든 댓글중에서 가장 최근에 작성된 5개의 댓글만 검색 -->
	<!-- 문제점 : XML 기반의 매퍼 파일에서는 SQL 명령이 등록된 엘리먼트에서 관계 연산자
	(> 또는 <)를 사용할 경우 엘리먼트를 표시하는 기호로 인식되어 에러 발생 -->
	<!-- 해결법-1 : 관계 연산자(> 또는 <)를 엔티티 레퍼런스(회피문자)로 변경하여 SQL 명령 작성 -->
	<!-- 해결법-2 : CDATA 세션을 사용하여 SQL 명령 작성 -->
	<select id="selectCountReplyList" resultType="MyReply">
		<!-- 
		select rownum,reply.* from (select * from myreply 
			order by reply_no desc) reply where rownum &lt;= 5
		 -->
		<![CDATA[
			select rownum,reply.* from (select * from myreply 
				order by reply_no desc) reply where rownum <= 5
		]]> 	  
	</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>
	
	<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="myReplyUserResultMap2">
		<!-- reultMap 속성 : reultMap 엘리먼트의 식별자를 속성값을 설정 -->
		<!-- => reultMap 엘리먼트로 설정된 매핑정보를 이용하여 검색행의 컬럼값을 객체 필드에
		저장하여 객체를 제공받아 포함 객체의 필드에 저장 -->
		<association property="reply" resultMap="myReplyResultMap"/>
		<!-- select 속성 : select 엘리먼트의 식별자를 속성값으로 설정 -->
		<!-- => select 엘리먼트의 SELECT 명령으로 실행된 검색결과를 객체로 제공받아 포함 객체 필드에 저장 -->
		<!-- column 속성 : SELECT 명령으로 검색된 행의 컬럼명을 속성값으로 설정 -->
		<!-- => SELECT 명령으로 검색된 행의 컬럼값을 select 속성값으로 설정된 select 엘리먼트
		의 parameterType 속성값으로 전달하여 SQL 명령에서 사용 -->
		<association property="user" select="selectMyUser" column="reply_id"/>
	</resultMap>
	
	<!-- association 엘리먼트에서만 사용하기 위한 SELECT 명령 등록 -->
	<!-- => parameterType 속성으로 전달받은 값으로 단일행이 검색되도록 SELECT 명령 작성 -->
	<!-- => DAO 클래스의 메소드에서 사용될 SQL 명령이 아니므로 Interface 기반의 맵퍼 파일에서
	추상메소드 미선언 -->
	<select id="selectMyUser" parameterType="string" resultType="MyUser">
		select * from myuser where user_id=#{userId}
	</select>
	
	<!-- 테이블 조인을 사용하지 않고 resultMap 엘리먼트의 매핑정보를 제공받아 2개 이상의
	테이블의 컬럼값을 검색하여 Java 객체로 제공 가능 -->
	<select id="selectReplyUserList2" resultMap="myReplyUserResultMap2">
		select * from myreply order by reply_no desc
	</select>
</mapper>





📙 interface 매퍼 (MYREPLY)

package xyz.itwill.mapper;

import java.util.List;

import xyz.itwill.dto.MyReply;
import xyz.itwill.dto.MyReplyUser;

public interface MyReplyMapper {
	int insertReply(MyReply reply);
	List<MyReply> selectReplyList();
	List<MyReply> selectCountReplyList();
	List<MyReplyUser> selectReplyUserList1();
	List<MyReplyUser> selectReplyUserList2();
}





📒 DAO class

  • insertReply() : 댓글 등록
  • selectReplyList() : MYREPLY 테이블에 저장된 모든 댓글 검색
  • selectCountReplyList() : MYREPLY 테이블에 저장된 모든 댓글중에서 가장 최근에 작성된 5개의 댓글만 검색
  • selectReplyUserList1() : join을 사용하여 댓글정보 검색
  • selectReplyUserList2() : 테이블 조인을 사용하지 않고 2개 이상의 테이블의 컬럼값을 검색하여 Java 객체로 제공 가능
package xyz.itwill.dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import xyz.itwill.dto.MyReply;
import xyz.itwill.dto.MyReplyUser;
import xyz.itwill.mapper.MyReplyMapper;

public class MyReplyDAO extends AbstractSession {
	private static MyReplyDAO _dao;
	
	private MyReplyDAO() {
		// TODO Auto-generated constructor stub
	}
	
	static {
		_dao=new MyReplyDAO();
	}
	
	public static MyReplyDAO getDAO() {
		return _dao;
	}
	
	public int insertReply(MyReply reply) {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyReplyMapper.class).insertReply(reply);
		} finally {
			sqlSession.close();
		}
	} 
	
	public List<MyReply> selectReplyList() {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyReplyMapper.class).selectReplyList();
		} finally {
			sqlSession.close();
		}
	}
	
	public List<MyReply> selectCountReplyList() {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyReplyMapper.class).selectCountReplyList();
		} finally {
			sqlSession.close();
		}
	}
	
	public List<MyReplyUser> selectReplyUserList1() {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyReplyMapper.class).selectReplyUserList1();
		} finally {
			sqlSession.close();
		}
	}
	
	public List<MyReplyUser> selectReplyUserList2() {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyReplyMapper.class).selectReplyUserList2();
		} finally {
			sqlSession.close();
		}
	}
}





🐣 댓글 등록

<%@page import="xyz.itwill.dao.MyReplyDAO"%>
<%@page import="xyz.itwill.dto.MyReply"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	//첫번째 게시글에 대한 댓글 삽입 - 3개
	MyReply reply1=new MyReply();
	reply1.setReplyCommentNo(1);
	reply1.setReplyId("xyz");
	reply1.setReplyContent("첫번째 게시글에 대한 댓글-1");
	MyReplyDAO.getDAO().insertReply(reply1);
	
	MyReply reply2=new MyReply();
	reply2.setReplyCommentNo(1);
	reply2.setReplyId("opq");
	reply2.setReplyContent("첫번째 게시글에 대한 댓글-2");
	MyReplyDAO.getDAO().insertReply(reply2);
	
	MyReply reply3=new MyReply();
	reply3.setReplyCommentNo(1);
	reply3.setReplyId("xyz");
	reply3.setReplyContent("첫번째 게시글에 대한 댓글-3");
	MyReplyDAO.getDAO().insertReply(reply3);
	//두번째 게시글에 대한 댓글 삽입 - 0개
	
	//세번째 게시글에 대한 댓글 삽입 - 1개
	MyReply reply4=new MyReply();
	reply4.setReplyCommentNo(3);
	reply4.setReplyId("abc");
	reply4.setReplyContent("세번째 게시글에 대한 댓글-1");
	MyReplyDAO.getDAO().insertReply(reply4);
	
	//네번째 게시글에 대한 댓글 삽입 - 2개
	MyReply reply5=new MyReply();
	reply5.setReplyCommentNo(4);
	reply5.setReplyId("xyz");
	reply5.setReplyContent("네번째 게시글에 대한 댓글-1");
	MyReplyDAO.getDAO().insertReply(reply5);
	
	MyReply reply6=new MyReply();
	reply6.setReplyCommentNo(4);
	reply6.setReplyId("opq");
	reply6.setReplyContent("네번째 게시글에 대한 댓글-2");
	MyReplyDAO.getDAO().insertReply(reply6);
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MYBATIS</title>
</head>
<body>
	<h1>댓글등록</h1>
	<hr>
	<h3>댓글이 성공적으로 삽입 되었습니다.</h3>
</body>
</html>





🐣 댓글 목록1 (ALL)

<%@page import="xyz.itwill.dao.MyReplyDAO"%>
<%@page import="xyz.itwill.dto.MyReply"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	List<MyReply> replyList=MyReplyDAO.getDAO().selectReplyList();
%>    
<!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; }
.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(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>





🐣 댓글 목록2 (최신글 5개)

<%@page import="xyz.itwill.dao.MyReplyDAO"%>
<%@page import="xyz.itwill.dto.MyReply"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	List<MyReply> replyList=MyReplyDAO.getDAO().selectCountReplyList();
%>    
<!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; }
.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(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>





🐣 댓글 목록3 (join user)

<%@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: 250px; }
.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.getUser().getUserName() %>(<%=replyUser.getUser().getUserId()%>)</td>
			<td><%=replyUser.getReply().getReplyContent() %></td>
			<td><%=replyUser.getReply().getReplyDate() %></td>
			<td><%=replyUser.getReply().getReplyCommentNo() %></td>
		</tr>	
		<% } %>
	</table>
</body>
</html>





🐣 댓글 목록4 (join 사용X)


<%@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: 250px; }
.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.getUser().getUserName() %>(<%=replyUser.getUser().getUserId()%>)</td>
			<td><%=replyUser.getReply().getReplyContent() %></td>
			<td><%=replyUser.getReply().getReplyDate() %></td>
			<td><%=replyUser.getReply().getReplyCommentNo() %></td>
		</tr>	
		<% } %>
	</table>
</body>
</html>





🌼 게시글에 대한 댓글 검색


📕 DTO class (1:N join)

  • MYCOMMENT 테이블과 MYREPLY 테이블의 검색결과를 저장하기 위한 클래스

    • 1:N 관계의 조인 검색 결과를 저장하기 위한 클래스

package xyz.itwill.dto;

import java.util.List;

public class MyCommentReply {
	private int commentNo;
	
	//MYCOMMENT 테이블(게시글정보)의 검색결과를 저장하기 위한 필드 - 검색행 : 1개
	private MyComment1 comment;
	
	//MYREPLY 테이블(댓글정보)의 검색결과를 저장하기 위한 필드 - 검색행 : 0개 이상
	private List<MyReply> replyList;
	
	public MyCommentReply() {
		// TODO Auto-generated constructor stub
	}
	
	public int getCommentNo() {
		return commentNo;
	}

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

	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;
	}
}





📕 DTO class (3table join)

  • MYCOMMENT 테이블과 MYUSER 테이블 및 MYREPLY 테이블과 MYUSER 테이블의 검색결과를 저장하기 위한 클래스

  • MYCOMMENT 테이블(게시글정보)의 검색결과를 저장하기 위한 필드 (검색행 : 1개)

    • 필드로 값 저장
  • MYUSER 테이블(회원정보 - 게시글)의 검색결과를 저장하기 위한 필드 (검색행 : 1개)

    • 객체를 저장할 수 있는 클래스로 필드 값 저장
  • MYREPLY 테이블(댓글정보)과 MYUSER 테이블(회원정보 - 댓글)의 검색결과를 저장하기 위한 필드 (검색행 : 0개 이상)

    • List객체로 필드 값 저장

package xyz.itwill.dto;

import java.util.List;

public class MyCommentReplyUser {
	//MYCOMMENT 테이블(게시글정보)의 검색결과를 저장하기 위한 필드 - 검색행 : 1개
	private int commentNo;
	private String commentId;
	private String commentContent;
	private String commentDate;
	
	//MYUSER 테이블(회원정보 - 게시글)의 검색결과를 저장하기 위한 필드 - 검색행 : 1개
	private MyUser user;
	
	//MYREPLY 테이블(댓글정보)과 MYUSER 테이블(회원정보 - 댓글)의 검색결과를 저장하기 위한 필드 - 검색행 : 0개 이상
	private List<MyReplyUser> replyUserList;
	
	public MyCommentReplyUser() {
		// 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 MyUser getUser() {
		return user;
	}

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

	public List<MyReplyUser> getReplyUserList() {
		return replyUserList;
	}

	public void setReplyUserList(List<MyReplyUser> replyUserList) {
		this.replyUserList = replyUserList;
	}
}





⭐ xml 매퍼 (comment)

  1. 메소드 두개(MyComment1, MyReply)를 작성하여 검색
  • 게시글번호를 전달받아 MYCOMMNET 테이블에 저장된 해당 게시글번호의 게시글을 검색하여 MyComment1 객체로 제공하는 엘리먼트 (검색행 : 1개)
  • 게시글번호를 전달받아 MYREPLY 테이블에 저장된 해당 게시글번호의 댓글을 검색하여 MuReply 객체로 제공하는 엘리먼트 (검색행 0개 이상)
  1. 메소드 한개(MyCommentReply)를 작성하여 검색 (1:N join)
  • 1:N 관계의 조인은 반드시 OUTER JOIN 사용하여 검색
    • 댓글이 없는 게시글을 검색하기 위해 LEFT OUTER JOIN 사용
  • resultMap 엘리먼트의 type 속성값으로 설정된 클래스의 필드 자료형이 List인 경우 collection 엘리먼트를 사용하여 List 객체를 생성하여 필드에 저장되도록 설정

    • collection: List 객체를 생성하여 포함 객체 필드에 저장하기 위한 엘리먼트
    • 1:N 관계의 테이블 조인에서 0개 이상의 검색행을 List 객체의 요소로 저장하여 생성
    • id 엘리먼트와 result 엘리먼트를 하위 엘리먼트로 사용하여 검색행의 컬럼값이 List 객체의 요소 필드에 저장되도록 설정
      • property 속성 : resultMap 엘리먼트의 type 속성값으로 설정된 클래스의 필드명을 속성값으로 설정
      • ofType 속성 : List 객체에 저장될 요소의 Java 자료형을 속성값으로 설정
      • Java 자료형 대신 typeAlias 엘리먼트로 설정된 별칭 사용 가능
    • <collection property="replyList" ofType="MyReply">

💡 resultMap 엘리리먼의 하위 엘리먼트 작성 순서

  • constructor, id, result, association, collection, discriminator
  • association 엘리먼트가 resultMap 엘리먼트의 첫번째 하위 엘리먼트인 경우 내부적으로 selectOne 메소드를 사용하여 하나의 검색행에 대한 객체만 제공하여 필드에 저장
    • 문제점) association 엘리먼트가 resultMap 엘리먼트의 첫번째 하위 엘리먼트인 경우 다수의 행이 검색된 경우 TooManyResultsException 발생
    • 해결법) 다수행을 검색할 경우 resultMap 엘리먼트의 첫번째 하위 엘리먼트를 association 엘리먼트가 아닌 다른 엘리먼트로 설정하여 매핑 처리

  1. 클래스(selectCommentReplyUser)의 필드로 값을 저장할 수 있는 MYCOMMENT 테이블의 필드, 객체를 저장할 수 있는 MYUSER 클래스, List객체인 MyReplyUser 저장(검색행: 0개 이상)
  • mycomment, myreply, myuser table join하여 검색
    • mycomment join myuser on comment_id=user_id (게시글과 작성자 join)
    • myreply join myuser on reply_id=user_id (댓글과 작성자 join)
    • mycomment join myreply on comment_no=reply_comment_no (게시글과 댓글 join)
  • autoMapping 속성 : false 또는 true 중 하나를 속성값으로 설정
    • autoMapping 속성값을 [true]로 설정한 경우 검색행의 컬럼명과 필드명이 같은 경우 자동 매핑 처리


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="xyz.itwill.mapper.MyCommentMapper">
	<!-- 게시글번호를 전달받아 MYCOMMNET 테이블에 저장된 해당 게시글번호의 게시글을 검색하여
	MyComment1 객체로 제공하는 엘리먼트 - 검색행 : 1개 -->
	<select id="selectComment" parameterType="int" resultType="MyComment1">
		select * from mycomment where comment_no=#{commentNo}
	</select>
	
	<!-- 게시글번호를 전달받아 MYREPLY 테이블에 저장된 해당 게시글번호의 댓글을 검색하여
	MuReply 객체로 제공하는 엘리먼트 - 검색행 : 0개 이상 -->
	<select id="selectCommentNoReplyList" parameterType="int" resultType="MyReply">
		select * from myreply where reply_comment_no=#{replyCommentNo} order by reply_no desc
	</select>
  
	
	<!-- resultMap 엘리먼트의 type 속성값으로 설정된 클래스의 필드 자료형이 List인 경우
	collection 엘리먼트를 사용하여 List 객체를 생성하여 필드에 저장되도록 설정 -->
	<!-- resultMap 엘리리먼의 하위 엘리먼트 작성 순서 -->
	<!-- => constructor, id, result, association, collection, discriminator -->
	<!-- => association 엘리먼트가 resultMap 엘리먼트의 첫번째 하위 엘리먼트인 경우 내부적으로
	selectOne 메소드를 사용하여 하나의 검색행에 대한 객체만 제공하여 필드에 저장 -->
	<!-- 문제점)association 엘리먼트가 resultMap 엘리먼트의 첫번째 하위 엘리먼트인 경우 다수의
	행이 검색된 경우 TooManyResultsException 발생 -->
	<!-- 해결법)다수행을 검색할 경우 resultMap 엘리먼트의 첫번째 하위 엘리먼트를 association
	엘리먼트가 아닌 다른 엘리먼트로 설정하여 매핑 처리 -->
	<resultMap type="MyCommentReply" id="myCommentReplyResultMap">
		<id column="comment_no" property="commentNo"/>	
	
		<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>
		
		<!-- collection: List 객체를 생성하여 포함 객체 필드에 저장하기 위한 엘리먼트 -->
		<!-- => 1:N 관계의 테이블 조인에서 0개 이상의 검색행을 List 객체의 요소로 저장하여 생성 -->
		<!-- => id 엘리먼트와 result 엘리먼트를 하위 엘리먼트로 사용하여 검색행의 컬럼값이
		List 객체의 요소 필드에 저장되도록 설정 -->
		<!-- property 속성 : resultMap 엘리먼트의 type 속성값으로 설정된 클래스의 필드명을 속성값으로 설정 -->
		<!-- ofType 속성 : List 객체에 저장될 요소의 Java 자료형을 속성값으로 설정 -->
		<!-- => Java 자료형 대신 typeAlias 엘리먼트로 설정된 별칭 사용 가능 -->
		<collection property="replyList" 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 comment_no,comment_id,comment_content,comment_date,reply_no,reply_id
			,reply_content,reply_date,reply_comment_no from mycomment left join
			myreply on comment_no=reply_comment_no where comment_no=#{commentNo}
			order by reply_no desc 
	</select>
	
	<!--  
	<resultMap type="MyCommentReplyUser" id="myCommentReplyUserResultMap">
		<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 property="user" javaType="MyUser">
			<id column="user_id" property="userId"/>
			<result column="user_name" property="userName"/>
		</association>
		
		<collection property="replyUserList" ofType="MyReplyUser">
			<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="reply_user_id" property="userId"/>
				<result column="reply_user_name" property="userName"/>
			</association>
		</collection>
	</resultMap>
	
	<select id="selectCommentReplyUser" parameterType="int" resultMap="myCommentReplyUserResultMap">
		select comment_no,comment_id,comment_content,comment_date,user_id,user_name,reply_no
			,reply_id,reply_content,reply_date,reply_comment_no,reply_user_id,reply_user_name
			from mycomment join myuser on comment_id=user_id left join 
			(select reply_no,reply_id,reply_content,reply_date,reply_comment_no
			,user_id reply_user_id,user_name reply_user_name from myreply join myuser 
			on reply_id=user_id) on comment_no=reply_comment_no 
			where comment_no=#{commentNo} order by reply_no desc 
	</select>
	-->
	
	<!-- autoMapping 속성 : false 또는 true 중 하나를 속성값으로 설정 -->
	<!-- => autoMapping 속성값을 [true]로 설정한 경우 검색행의 컬럼명과 필드명 같은 경우 자동 매핑 처리 -->
	<resultMap type="MyCommentReplyUser" id="myCommentReplyUserResultMap" autoMapping="true">
		<id column="comment_no" property="commentNo"/>
		<association property="user" javaType="MyUser" autoMapping="true"/>
		<collection property="replyUserList" select="selectReplyUser" column="comment_no"/>
	</resultMap>
	
	<resultMap type="MyReplyUser" id="myReplyUserResultMap" autoMapping="true">
		<association property="reply" javaType="MyReply" autoMapping="true"/>
		<association property="user" javaType="MyUser" autoMapping="true"/>
	</resultMap>
	
	<select id="selectReplyUser" parameterType="int" resultMap="myReplyUserResultMap">
		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 where reply_comment_no=#{replyCommentNo} order by reply_no desc
	</select>
	
	<select id="selectCommentReplyUser" parameterType="int" resultMap="myCommentReplyUserResultMap">
		select comment_no,comment_id,comment_content,comment_date,user_id,user_name
			,reply_no,reply_id,reply_content,reply_date,reply_comment_no
			from mycomment join myuser on comment_id=user_id left join myreply on comment_no=reply_comment_no 
			where comment_no=#{commentNo} order by reply_no desc 
	</select>
</mapper>






📙 interface 매퍼 (comment)

package xyz.itwill.mapper;


public interface MyCommentMapper {
	MyComment1 selectComment(int commentNo);
	List<MyReply> selectCommentNoReplyList(int replyCommentNo);
	MyCommentReply selectCommentReply(int commentNo);
	MyCommentReplyUser selectCommentReplyUser(int commentNo);
}





📒 DAO class (comment)

  • selectComment() : 전달받은 게시글번호에 대한 게시글(1개)을 검색하여 반환

  • selectCommentNoReplyList() : 전달받은 게시글번호에 대한 댓글(0개 이상)을 검색하여 반환

  • selectCommentReply() : MyComment1과 MyReply table을 join 하여 댓글목록 검색

  • selectCommentReplyUser() : MyComment1, MyReply, MyUser table을 join 하여 댓글목록 검색

package xyz.itwill.dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import xyz.itwill.dto.MyComment1;
import xyz.itwill.dto.MyComment2;
import xyz.itwill.dto.MyComment3;
import xyz.itwill.dto.MyCommentReply;
import xyz.itwill.dto.MyCommentReplyUser;
import xyz.itwill.dto.MyCommentUser1;
import xyz.itwill.dto.MyCommentUser2;
import xyz.itwill.dto.MyReply;
import xyz.itwill.mapper.MyCommentMapper;

public class MyCommentDAO extends AbstractSession {
	private static MyCommentDAO _dao;
	
	private MyCommentDAO() {
		// TODO Auto-generated constructor stub
	}
	
	static {
		_dao=new MyCommentDAO();
	}
	
	public static MyCommentDAO getDAO() {
		return _dao;
	}
	
	
	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 replyCommentNo) {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyCommentMapper.class).selectCommentNoReplyList(replyCommentNo);
		} finally {
			sqlSession.close();
		}
	}
	
	public MyCommentReply selectCommentReply(int commentNo) {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyCommentMapper.class).selectCommentReply(commentNo);
		} finally {
			sqlSession.close();
		}
	}
	
	public MyCommentReplyUser selectCommentReplyUser(int commentNo) {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyCommentMapper.class).selectCommentReplyUser(commentNo);
		} finally {
			sqlSession.close();
		}
	}
}





🐣 게시글 목록

  • 게시글 내용을 클릭 시 게시글 번호를 전달하여 게시글에 대한 댓글 목록 뷰로 이동

<%@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()%>"> --%>
				<a href="commentReplySelect2.jsp?commentNo=<%=commentUser.getComment().getCommentNo()%>">
					<%=commentUser.getComment().getCommentContent() %>
				</a>
			</td>
			<td><%=commentUser.getComment().getCommentDate() %></td>
		</tr>
		<% } %>
	</table>	
</body>
</html>





🐣 댓글목록 검색 (메소드2개)

  • 게시글 내용을 클릭 할 경우 전달값(게시글번호)을 반환받아 저장

    • int commentNo=Integer.parseInt(request.getParameter("commentNo"));
  • 전달받은 게시글번호에 대한 게시글(1개)을 검색하여 반환하는 DAO 클래스의 메소드 호출

    • MyComment1 comment=MyCommentDAO.getDAO().selectComment(commentNo);
  • 전달받은 게시글번호에 대한 댓글(0개 이상)을 검색하여 반환하는 DAO 클래스의 메소드 호출

    • List<MyReply> replyList=MyCommentDAO.getDAO().selectCommentNoReplyList(commentNo);

<%@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"));
	
	//전달받은 게시글번호에 대한 게시글(1개)을 검색하여 반환하는 DAO 클래스의 메소드 호출
	MyComment1 comment=MyCommentDAO.getDAO().selectComment(commentNo);
	
	//전달받은 게시글번호에 대한 댓글(0개 이상)을 검색하여 반환하는 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: 250px; }
.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>





🐣 댓글목록 검색 (메소드1개)

  • 전달값(게시글번호)을 반환받아 저장

  • 전달받은 게시글번호에 대한 게시글과 댓글목록을 검색하여 반환하는 DAO 클래스의 메소드 호출

<%@page import="xyz.itwill.dto.MyCommentReply"%>
<%@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"));
	
	//전달받은 게시글번호에 대한 게시글과 댓글목록을 검색하여 반환하는 DAO 클래스의 메소드 호출
	MyCommentReply commentReply=MyCommentDAO.getDAO().selectCommentReply(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: 250px; }
.date { width: 200px; }
.comment { width: 100px; }
</style>
</head>
<body>
	<h1>게시글과 댓글목록</h1>
	<hr>
	<%-- 게시글 출력 --%>
	<table>
		<tr>
			<td width="200">게시글번호</td>
			<td width="300"><%=commentReply.getComment().getCommentNo() %></td>
		</tr>
		<tr>
			<td width="200">게시글작성자</td>
			<td width="300"><%=commentReply.getComment().getCommentId() %></td>
		</tr>
		<tr>
			<td width="200">게시글내용</td>
			<td width="300"><%=commentReply.getComment().getCommentContent() %></td>
		</tr>
		<tr>
			<td width="200">게시글작성일</td>
			<td width="300"><%=commentReply.getComment().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(commentReply.getReplyList().isEmpty()) { %>
		<tr>
			<td colspan="5">댓글이 존재하지 않습니다.</td>
		</tr>
		<% } else { %>
			<% for(MyReply reply:commentReply.getReplyList()) { %>
			<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>





🐣 댓글목록 검색 (3table join)

  • 전달값(게시글번호)을 반환받아 저장

  • 전달받은 게시글번호에 대한 게시글과 댓글목록을 검색하여 반환하는 DAO 클래스의 메소드 호출

    • mycomment join myuser on comment_id=user_id (게시글과 작성자 join)
    • myreply join myuser on reply_id=user_id (댓글과 작성자 join)
    • mycomment join myreply on comment_no=reply_comment_no (게시글과 댓글 join)

<%@page import="xyz.itwill.dto.MyReplyUser"%>
<%@page import="xyz.itwill.dto.MyCommentReplyUser"%>
<%@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"));
	
	//전달받은 게시글번호에 대한 게시글과 댓글목록을 검색하여 반환하는 DAO 클래스의 메소드 호출
	MyCommentReplyUser commentReplyUser=MyCommentDAO.getDAO().selectCommentReplyUser(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: 250px; }
.date { width: 200px; }
.comment { width: 100px; }
</style>
</head>
<body>
	<h1>게시글과 댓글목록</h1>
	<hr>
	<%-- 게시글 출력 --%>
	<table>
		<tr>
			<td width="200">게시글번호</td>
			<td width="300"><%=commentReplyUser.getCommentNo() %></td>
		</tr>
		<tr>
			<td width="200">게시글작성자</td>
			<td width="300"><%=commentReplyUser.getUser().getUserName()%>(<%=commentReplyUser.getUser().getUserId()%>) </td>
		</tr>
		<tr>
			<td width="200">게시글내용</td>
			<td width="300"><%=commentReplyUser.getCommentContent() %></td>
		</tr>
		<tr>
			<td width="200">게시글작성일</td>
			<td width="300"><%=commentReplyUser.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(commentReplyUser.getReplyUserList().isEmpty()) { %>
		<tr>
			<td colspan="5">댓글이 존재하지 않습니다.</td>
		</tr>
		<% } else { %>
			<% for(MyReplyUser replyUser:commentReplyUser.getReplyUserList()) { %>
			<tr>
				<td><%=replyUser.getReply().getReplyNo() %></td>
				<td><%=replyUser.getUser().getUserName()%>(<%=replyUser.getUser().getUserId()%>) </td>
				<td><%=replyUser.getReply().getReplyContent() %></td>
				<td><%=replyUser.getReply().getReplyDate() %></td>
				<td><%=replyUser.getReply().getReplyCommentNo() %></td>
			</tr>
			<% } %>
		<% } %>
	</table>
</body>
</html>





profile
Study Log 📂

0개의 댓글