게시판 만들기 (댓글 쓰기 / 댓글 목록/ 댓글 갯수)
Back-End/Spring 2019. 7. 4. 14:18게시판 만들기 (댓글 쓰기 / 댓글 쓰기 / 댓글 갯수)
데이터베이스에서 중복될 위험을 방지하기위해 reply 테이블 및 관련 제약조건을 삭제
1
|
drop table reply cascade constraints;
|
cs |
댓글 관련 자료를 저장할 reply 테이블을 생성
1
2
3
4
5
6
7
8
|
create table reply (
rno number not null primary key, //댓글의 고유번호, null값이 들어갈 수 없고, 기본키로 설정함
bno number default 0, //게시글(원글)의 번호, 기본값을 0으로 설정
replytext varchar2(1000) not null, //댓글 내용의 글자수를 설정하고, null값이 들어가지 못하게함
replyer varchar2(50) not null, //댓글 작성자 아이디의 글자수를 설정하고, null값이 들어가지 못하게함
regdate date default sysdate, //댓글 작성 날짜의 기본값을 현재 시간으로 설정함
updatedate date default sysdate //댓글 수정 날짜의 기본값을 현재 시간으로 설정함
);
|
cs |
다른테이블의 기본키를 참조할 외래키를 설정 (제약조건을 설정) - 원글과 꼬이는 것을 방지하기 위해서
(댓글과 원글이 꼬이면 안되기 때문에.. 예를 들면 기존에 게시글이 삭제되면 그 게시글에 달려있는 댓글도 같이 삭제되어야 한다.)
1
2
|
alter table reply add constraint fk_board //reply테이블의 bno속성을 board테이블의 기본키인 (bno)를 참조하는 외래키로 설정함
foreign key(bno) references board(bno); //또한 board테이블의 (bno)의 값이 변경되면 연쇄적으로 reply테이블의 (bno)의 값도 같이 변경된다.
|
cs |
댓글 번호 관리를 위한 시퀀스를 설정하기 위해 설정
1
2
3
4
|
drop sequence reply_seq; //중복될수도 있으니 시퀀스를 삭제.
create sequence reply_seq //시작값을 1로하고 1씩 증가하는 reply_seq 시퀀스를 생성함.
start with 1
increment by 1;
|
cs |
작업후에 결과를 반영하기 위해 commit 하기
1
|
commit;
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<!-- 댓글 작성 -->
<!-- 너비와 정렬방식 설정 -->
<div style="width:700px; text-align:center;">
<!-- 세션에 저장되어있는 userid가 null이 아닐때 -->
<!-- 그러니까 로그인을 한 상태이어야만 댓글을 작성 할 수 있다.-->
<c:if test="${sessionScope.userid != null }">
<textarea rows="5" cols="80" id="replytext"
placeholder="댓글을 작성하세요"></textarea>
<br>
<!-- 댓글쓰기 버튼을 누르면 id값인 btnReply값이 넘어가서 -->
<!-- 위쪽에 있는 스크립트 구문이 실행되고 -->
<!-- 내가 댓글을 작성한 값이 스크립트문을 거쳐서 컨트롤러로 맵핑되게 된다. -->
<button type="button" id="btnReply">댓글쓰기</button>
</c:if>
</div>
<!-- 댓글 목록 -->
<!-- 댓글이 등록이 되면 listReply에 댓글이 쌓이게 된다 -->
<div id="listReply"></div>
</body>
</html>
|
cs |
댓글 관련 자료를 저장할 DTO를 생성
ReplyDTO.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
package com.example.spring02.model.board.dto;
import java.util.Date;
public class ReplyDTO {
private int rno; //댓글 번호
private int bno; //게시물 번호
private String replytext; //댓글 내용
private String replyer; //댓글 작성자 id
private String name; //댓글 작성자 이름
private Date regdate; //java.util.Date, 작성일자
private Date updatedate; //수정일자
private String secret_reply; //비밀댓글 여부
private String writer; //member 테이블의 id
//getter,setter,toString()
public int getRno() {
return rno;
}
public void setRno(int rno) {
this.rno = rno;
}
public int getBno() {
return bno;
}
public void setBno(int bno) {
this.bno = bno;
}
public String getReplytext() {
return replytext;
}
public void setReplytext(String replytext) {
this.replytext = replytext;
}
public String getReplyer() {
return replyer;
}
public void setReplyer(String replyer) {
this.replyer = replyer;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getRegdate() {
return regdate;
}
public void setRegdate(Date regdate) {
this.regdate = regdate;
}
public Date getUpdatedate() {
return updatedate;
}
public void setUpdatedate(Date updatedate) {
this.updatedate = updatedate;
}
public String getSecret_reply() {
return secret_reply;
}
public void setSecret_reply(String secret_reply) {
this.secret_reply = secret_reply;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
@Override
public String toString() {
return "ReplyDTO [rno=" + rno + ", bno=" + bno + ", replytext=" + replytext + ", replyer=" + replyer + ", name="
+ name + ", regdate=" + regdate + ", updatedate=" + updatedate + ", secret_reply=" + secret_reply + ", writer="
+ writer + "]";
}
}
|
cs |
ReplyController.java 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
package com.example.spring02.controller.board;
import java.util.List;
import javax.inject.Inject;
import javax.servlet.http.HttpSession;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import com.example.spring02.model.board.dto.ReplyDTO;
import com.example.spring02.service.board.ReplyService;
// @ResponseBody를 붙이지 않아도 뷰가 아닌 데이터 리턴 가능
@RestController // spring 4.0부터 사용 가능
@RequestMapping("reply/*") //공통적인 url pattern
public class ReplyController {
@Inject //서비스를 호출하기위해서 의존성을 주입
ReplyService replyService;
//댓글리스트를 호출할때 맵핑되는 메소드
@RequestMapping("list.do")
public ModelAndView list(int bno, ModelAndView mav) {
List<ReplyDTO> list=replyService.list(bno); //댓글 목록
mav.setViewName("board/reply_list"); //뷰의 이름
mav.addObject("list", list); //뷰에 전달할 데이터 저장
return mav; //뷰로 이동
}
//댓글 목록을 ArrayList로 리턴
@RequestMapping("list_json.do")
public List<ReplyDTO> list_json(int bno){
return replyService.list(bno);
}
@RequestMapping("insert.do") //세부적인 url pattern
public void insert(ReplyDTO dto, HttpSession session) {
//댓글 작성자 아이디
//현재 접속중인 사용자 아이디
String userid=(String)session.getAttribute("userid");
dto.setReplyer(userid);
//댓글이 테이블에 저장됨
replyService.create(dto);
//jsp 페이지로 가거나 데이터를 리턴하지 않음
}
}
|
cs |
ReplyService.java 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package com.example.spring02.service.board;
import java.util.List;
import com.example.spring02.model.board.dto.ReplyDTO;
public interface ReplyService {
public List<ReplyDTO> list(int bno); //댓글 리스트
public int count(int bno); //댓글 수
public void create(ReplyDTO dto); //댓글 작성
}
|
cs |
ReplyServiceImpl.java 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
package com.example.spring02.service.board;
import java.util.List;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import com.example.spring02.model.board.dao.ReplyDAO;
import com.example.spring02.model.board.dto.ReplyDTO;
@Service //service bean
public class ReplyServiceImpl implements ReplyService {
@Inject
ReplyDAO replyDao; //dao를 호출하기위해서 의존성을 주입
//댓글 목록
@Override
public List<ReplyDTO> list(int bno) {
return replyDao.list(bno);
}
@Override
public int count(int bno) {
return 0;
}
//댓글 쓰기
@Override
public void create(ReplyDTO dto) {
replyDao.create(dto);
}
}
|
cs |
ReplyDAO.java
1
2
3
4
5
6
7
8
9
10
11
12
|
package com.example.spring02.model.board.dao;
import java.util.List;
import com.example.spring02.model.board.dto.ReplyDTO;
public interface ReplyDAO {
public List<ReplyDTO> list(int bno); //댓글 목록
public int count(int bno); //댓글 수
public void create(ReplyDTO dto); //댓글 작성
}
|
cs |
ReplyDAOImpl.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
package com.example.spring02.model.board.dao;
import java.util.List;
import javax.inject.Inject;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;
import com.example.spring02.model.board.dto.ReplyDTO;
@Repository //dao bean
public class ReplyDAOImpl implements ReplyDAO {
@Inject //의존관계 주입
SqlSession sqlSession;
//댓글 목록
@Override
public List<ReplyDTO> list(int bno) {
return sqlSession.selectList("reply.listReply", bno);
}
@Override
public int count(int bno) {
return 0;
}
//댓글 추가
@Override
public void create(ReplyDTO dto) {
sqlSession.insert("reply.insertReply", dto);
}
}
|
cs |
replyMapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 다른 mapper와 중복되지 않도록 네임스페이스 기재 -->
<mapper namespace="reply">
<insert id="insertReply">
<!-- 댓글을 추가 (댓글번호, 글번호, 댓글내용, 댓글작성자를 추가 댓글번호는 시퀀스로 추가 -->
insert into reply (rno,bno,replytext,replyer) values
( reply_seq.nextval, #{bno}, #{replytext}, #{replyer} )
</insert>
<select id="listReply"
resultType="com.example.spring02.model.board.dto.ReplyDTO">
<!-- 댓글의 작성자와 회원 아이디가 같고, 글번호가 같을 경우에 댓글 리스트를 검색 (내림차순으로)-->
select rno,bno,replyer,regdate,updatedate,name,replytext
from reply r, member m
where r.replyer=m.userid and bno=#{bno}
order by rno
</select>
</mapper>
|
cs |
view.jsp
1
2
3
4
5
6
7
8
9
10
11
12
|
//댓글 목록 출력 함수
function listReply(num){
$.ajax({
type: "post", //post방식으로 자료를
url: "${path}/reply/list.do?bno=${dto.bno}&curPage", //컨트롤러에 있는 list.do로 맵핑하고 현재페이지와 게시판 번호도 같이 보낸다.
success: function(result){ //자료를 보내는것이 성공했을때 출력되는 메시지
//result : responseText 응답텍스트(html)
console.log(result);
$("#listReply").html(result);
}
});
}
|
cs |
댓글 갯수 확인 쿼리
1
2
3
4
5
|
select bno, title, writer, name, regdate, viewcnt,
(select count(*) from reply where bno = b.bno)cnt //게시글 번호, 제목, 작성자, 이름, 시간, 조회수, 그리고 댓글의 수를 검색 (cnt라는 약자로함)
from board b, member m //테이블 2개를 조인.
where b.writer = m.userid //board의 writer과 member의 userid가 같은것만
order by bno desc; //조건에 맞는 자료를 게시글 번호의 내림차순으로 검색
|
cs |
이 쿼리를 사용하기 위해 boardMapper.xml에 추가함
boardMapper.xml (listAll에 있는 쿼리문을 수정. 댓글의 개수를 제목옆에 출력할 수 있도록)
1
2
3
4
5
6
7
8
9
10
|
<select id="listAll"
resultType="com.example.spring02.model.board.dto.BoardDTO">
<!-- 결과는 boardDTO타입이 된 -->
<include refid="paging_header" />
<!-- ref는 다른테이블을 의미한다. -->
<!-- 번호, 제목, 작성자, 이름, 날짜, 조회수 , 그리고 댓글의 갯수를 검색 -->
<!-- board 테이블과 member 테이블로 부터 검색 -->
|
cs |
list.jsp에 방금 사용한 쿼리의 댓글 개수 (cnt값) 을 출력하기 위해 값을 받아온다.
1
2
3
|
<c:if test="${row.cnt > 0}"> //댓글의 개수가 0보다 크면 실행되는 구문
<span style="color:red;">( ${row.cnt} )</span> //댓글의 개수를 출력하고 색깔을 빨간색으로 한다.
</c:if>
|
cs |
아래 책은 제가 공부할때 활용했던 책으로 추천드리는 책이니 한번씩 읽어보시는것을 추천드립니다!! ㅎㅎ
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
'Back-End > Spring' 카테고리의 다른 글
게시판 만들기 (게시물 수정, 파일 첨부, 첨부파일 삭제, 게시물 삭제) (0) | 2019.07.04 |
---|---|
AJAX 방식 (0) | 2019.07.04 |
게시판 만들기 (상세화면) (0) | 2019.07.04 |
게시판 만들기 (검색기능) (0) | 2019.07.03 |
게시판 만들기 (페이지 나누기) (1) | 2019.07.03 |