본문 바로가기
Spring/study

spring 22강 게시판 만들기3( 상세 화면, 댓글 쓰기/댓글 목록/댓글 갯수)

by avvin 2019. 7. 4.

spring 22강 게시판 만들기3( 상세 화면, 댓글 쓰기/댓글 목록/댓글 갯수)



게시판 상세화면 (view.jsp)


list.jsp

title에 view.do 하이퍼링크

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
<table border="1" width="600px">
    <tr>
        <th>번호</th>
        <th>제목</th>
        <th>이름</th>
        <th>날짜</th>
        <th>조회수</th>
    </tr>
    <!-- forEach var="개별데이터" items="집합데이터" -->
<c:forEach var="row" items="${map.list}">
    <tr>
        <td>${row.bno}</td>
        <td>
<a href="${path}/board/view.do?bno=${row.bno}">
${row.title}
</a>
            <c:if test="${row.cnt > 0}">
                <span style="color:red;">( ${row.cnt} )</span>
            </c:if>   
        </td>
        <td>${row.name}</td>
        <td><fmt:formatDate value="${row.regdate}"
            pattern="yyyy-MM-dd HH:mm:ss"/> </td>
        <td>${row.viewcnt}</td>
    </tr>
</c:forEach>

cs



1
2
3
<a href="${path}/board/view.do?bno=${row.bno}&curPage=${map.pager.curPage}&search_option=${map.search_option}&keyword=${map.keyword}">
${row.title}
</a>


(강의에선 현재페이지, 검색옵션, 키워드 모두 GET방식으로 넘겨주어 controller view.do에서 받아준다. 어디서 쓰는진 모르겠음)




댓글쓰기 (view.jsp) 


댓글.sql

create table reply(

rno number not null primary key, --댓글 번호

bno number default 0, -- 어떤 게시글에 추가로 다는 것이기 때문에 원글 번호 필요 

replytext varchar2(1000) not null,

replyer varchar2(50) not null, --댓글작성자 아이디 

regdate date default sysdate, -- 댓글 작성 날짜

updatedate date default sysdate -- 댓글 수정 날짜

);


--foreign key 제약조건 추가


alter table reply add constraint fk_board

foreign key(bno) references board(bno); -- board테이블의 게시물(원글)번호와 일치하는 내용만 들어갈 수 제약 추가 ★


-- 댓글 번호 관리를 위한 시퀀스 생성


create sequence reply_seq

start with 1

increment by 1;  -- // 자꾸 increament로 오타냄 ㅠㅠ


commit;





view.jsp [ 댓글 작성을 위한 폼 ]

1
2
3
4
5
6
7
8
9
10
11
12

<!-- 댓글 작성 -->
<div style="width:700px; text-align:left;">
     <c:if test="${sessionScope.userid != null }">
         <textarea rows="5" cols="80" id="replytext"
             placeholder="댓글을 작성하세요"></textarea>
         <br>
         <button type="button" id="btnReply">댓글쓰기</button>
     </c:if>
</div>
<!-- 댓글 목록 -->
<div id="listReply"></div>


 

form을 사용하지 않고 ajax 방식 사용 


로그인 상태일때만 댓글창 O


textarea id =replytext 는 댓글 내용 자바스크립트 함수에 전달하기위한 id


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
<script>
$(function(){ //자동으로 실행되는 코드
    //댓글 목록 출력
    listReply2();
    
    //댓글 쓰기
    $("#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",
            data: param,
            success: function(){
                alert("댓글이 등록되었습니다.");
                listReply2(); //댓글 목록 출력
            }
        });
    });
    
//댓글 목록 출력 
function listReply2(){
    $.ajax({
        type: "get",
        contentType: "application/json",
        url: "${path}/reply/list_json.do?bno=${dto.bno}",
        success: function(result){
            
            console.log(result);
            var output="<table>";
            for(var i in result){
                var repl=result[i].replytext;
                repl = repl.replace(/  /gi,"&nbsp;&nbsp;");//공백처리
                repl = repl.replace(/</gi,"&lt;"); //태그문자 처리
                repl = repl.replace(/>/gi,"&gt;");
                repl = repl.replace(/\n/gi,"<br>"); //줄바꿈 처리
                
                output += "<tr><td>"+result[i].name;
                date = changeDate(result[i].regdate);
                output += "("+date+")";
                output += "<br>"+repl+"</td></tr>";
                
            }
            output += "</table>";
            $("#listReply").html(output);
        }
    });
}
 
 
}
 
</script>




( 강의에선 #btnReply로 실행되는 함수 블럭안의 코드를 reply()라는 함수로 빼주고 댓글도 페이지 나누기 기능을 넣음. )






ReplyDTO.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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() 코드 생략...    
}




댓글 목록 / 댓글 쓰기 기능 필요


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




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
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;
 
    //댓글 목록
    @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);
    }
}





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
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);
    }
    //view.jsp에서 댓글쓰기
    @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 페이지로 가거나 데이터를 리턴하지 않음
    }
}



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    //목록 버튼
    $("#btnList").click(function(){
        location.href="${path}/board/list.do";
    });
    //수정 버튼
    $("#btnUpdate").click(function(){
        //첨부파일 이름들을 폼에 추가
        var str="";
        $("#uploadedList .file").each(function(i){
            str+=
                "<input type='hidden' name='files["+i+"]' value='"
                +$(this).val()+"'>";
        });
        $("#form1").append(str);
        document.form1.action="${path}/board/update.do";
        document.form1.submit();
    });
    //삭제 버튼
    $("#btnDelete").click(function(){
        if(confirm("삭제하시겠습니까?")){
            document.form1.action="${path}/board/delete.do";
            document.form1.submit();
        }
    });






replyMapper.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?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>




reply_list.jsp

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
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <!-- views/board/reply_list.jsp -->
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<%@ include file="../include/header.jsp" %>
</head>
<body>
<% pageContext.setAttribute("newLineChar""\n"); %>
<table style="width:700px">
<c:forEach var="row" items="${list}">   
    <c:set var="str"
value="${fn:replace(row.replytext,'<','&lt;') }" />
    <c:set var="str"
value="${fn:replace(str,'>','&gt;') }" />    
    <c:set var="str"  
value="${fn:replace(str,'  ','&nbsp;&nbsp;')}" />
    <c:set var="str"
value="${fn:replace(str,newLineChar,'<br>') }" />    
    
    <tr>
        <td>
            ${row.name}
            ( <fmt:formatDate value="${row.regdate}"
                 pattern="yyyy-MM-dd a HH:mm:ss" /> )<br>
            ${str}
        </td>
    </tr>
</c:forEach>    
</table>
 
</body>
</html>





게시글 목록에서 제목 옆에 댓글 개수 표시하기



boardmapper.xml [ id="listAll" ]

1
2
3
4
5
6
7
8
9
10
<select id="listAll"
resultType="com.example.spring02.model.board.dto.BoardDTO">
        <include refid="paging_header" />
            select bno,title,writer,name,regdate,viewcnt,show
                  ,(select count(*from reply where bno=b.bno) cnt                    
            from board b, member m
            <include refid="search" />
            order by bno desc   
        <include refid="paging_footer" />
    </select>



list.jsp 글 제목부분

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<c:forEach var="row" items="${map.list}">
    <tr>
        <td>${row.bno}</td>
        <td>
<a href="${path}/board/view.do?bno=${row.bno}">
${row.title}
</a>
            <c:if test="${row.cnt > 0}">
                <span style="color:red;">${row.cnt} )</span>
            </c:if>   
        </td>
        <td>${row.name}</td>
        <td><fmt:formatDate value="${row.regdate}"
            pattern="yyyy-MM-dd HH:mm:ss"/> </td>
        <td>${row.viewcnt}</td>
    </tr>
</c:forEach>