'댓글 갯수'에 해당되는 글 1건

  1. 2019.07.04 게시판 만들기 (댓글 쓰기 / 댓글 목록/ 댓글 갯수) 2

게시판 만들기 (댓글 쓰기 / 댓글 목록/ 댓글 갯수)

Back-End/Spring 2019. 7. 4. 14:18
728x90
반응형

게시판 만들기 (댓글 쓰기 / 댓글 쓰기 / 댓글 갯수)

 

 

데이터베이스에서 중복될 위험을 방지하기위해 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(1000not null, //댓글 내용의 글자수를 설정하고, null값이 들어가지 못하게함
replyer varchar2(50not 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
 
 
view.jsp 중 일부
"댓글쓰기" 버튼을 누르면 서버에 저장이 되고 저장된 목록을 출력할 예정
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>
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//댓글 쓰기 (버튼을 눌러서 id값이 넘어와 실행되는 자바스크립트 구문)
    $("#btnReply").click(function(){
        var replytext=$("#replytext").val(); //댓글 내용
        var bno="${dto.bno}"//게시물 번호
        var param="replytext": replytext, "bno": bno};
        //var param="replytext="+replytext+"&bno="+bno;
        $.ajax({
            type: "post", //데이터를 보낼 방식
            url: "${path}/reply/insert.do", //데이터를 보낼 url
            data: param, //보낼 데이터
 
            success: function(){ //데이터를 보내는것이 성공했을시 출력되는 메시지
                alert("댓글이 등록되었습니다.");
                listReply2(); //댓글 목록 출력
            }
        });
    });
cs
     
</c:if>
</div>
<!-- 댓글 목록 -->
<!-- 댓글이 등록이 되면 listReply에 댓글이 쌓이게 된다 -->
<div id="listReply"></div>
 
1
2
3
4
5
6
7
8
9
10
11
//댓글 목록 출력 함수
function listReply(){
    $.ajax({
        type: "get", //get방식으로 자료를 전달한다
        url: "${path}/reply/list.do?bno=${dto.bno}", //컨트롤러에 있는 list.do로 맵핑하고 게시판 번호도 같이 보낸다.
        success: function(result){ //자료를 보내는것이 성 공했을때 출력되는 메시지
            //result : responseText 응답텍스트(html)
            $("#listReply").html(result);
        }
    });
}
cs
 
 
 
</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 테이블로 부터 검색 -->
            select bno,title,writer,name,regdate,viewcnt,show
   ,(select count(*) from reply where bno=b.bno) cnt                    
             from board b, member m
 
                Colored by Color Scripter
cs

 

 

list.jsp에 방금 사용한 쿼리의 댓글 개수 (cnt값) 을 출력하기 위해 값을 받아온다.

1
2
3
<c:if test="${row.cnt > 0}"> //댓글의 개수가 0보다 크면 실행되는 구문
    <span style="color:red;">( ${row.cnt} )</span> //댓글의 개수를 출력하고 색깔을 빨간색으로 한다.
</c:if>   
cs

아래 책은 제가 공부할때 활용했던 책으로 추천드리는 책이니 한번씩 읽어보시는것을 추천드립니다!! ㅎㅎ

토비의 스프링 3.1 세트:스프링의 이해와 원리 + 스프링의 기술과, 에이콘출판

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

 

728x90
반응형
: