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," ");//공백처리 repl = repl.replace(/</gi,"<"); //태그문자 처리 repl = repl.replace(/>/gi,">"); 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,'<','<') }" /> <c:set var="str" value="${fn:replace(str,'>','>') }" /> <c:set var="str" value="${fn:replace(str,' ',' ')}" /> <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> |
'Spring > study' 카테고리의 다른 글
spring 23강 게시판 만들기4( 게시물 수정 ) (0) | 2019.07.08 |
---|---|
@RequestBody 어노테이션과 @ReponseBody 어노테이션의 사용 (0) | 2019.07.05 |
selectOne / selectList 쓰임 차이 (0) | 2019.07.04 |
spring 21강 게시판 만들기2( 페이지 나누기, 검색 기능 ) (0) | 2019.07.04 |
spring 20강 게시판 만들기1(목록, 글쓰기) (0) | 2019.07.03 |