SPRING - SPRING FRAMEWORK 3 게시판 댓글

최성현·2023년 10월 18일
0

SPRING FRAMEWORK 3

목록 보기
10/10

설정

SPRING - SPRING FRAMEWORK 3 게시판 답글 설정에서 유지
+) pom.xml에 json repository추가
+) mybatis-config.xml에 dto 추가

db

  • db 데이터값
  • foreign key 설정

AnswerDto.java

package answer.data;

import java.sql.Timestamp;

public class AnswerDto {

	private int idx;
	private int num;
	private String nickname;
	private String pass;
	private String content;
	private Timestamp writeday;
	public int getIdx() {
		return idx;
	}
	public void setIdx(int idx) {
		this.idx = idx;
	}
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public String getNickname() {
		return nickname;
	}
	public void setNickname(String nickname) {
		this.nickname = nickname;
	}
	public String getPass() {
		return pass;
	}
	public void setPass(String pass) {
		this.pass = pass;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public Timestamp getWriteday() {
		return writeday;
	}
	public void setWriteday(Timestamp writeday) {
		this.writeday = writeday;
	}
	
}

insert

answerMapper.xml

	<insert id="insertOfReanswer" parameterType="adto">
		insert into reanswer (num,nickname,pass,content,writeday) values (#{num},#{nickname},#{pass},#{content},now())
	</insert>

AnswerDaoInter.java

public void insertAnswer(AnswerDto dto);

AnswerDao.java

	@Override
	public void insertAnswer(AnswerDto dto) {
		// TODO Auto-generated method stub
		session.insert("insertOfReanswer", dto);
	}

AnswerController.java

list출력은 BoardContentController에서 한다

package answer.data;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class AnswerController {
	
	@Autowired
	AnswerDao adao;
	
	@PostMapping("/board/ainsert") // 중간경로 전부 board로 해줘서 db가 바뀌어도 board가 중간경로
	public ModelAndView answerinsert(@ModelAttribute AnswerDto dto,
			@RequestParam String currentPage)
	{
		ModelAndView model=new ModelAndView();
		
		//db추가
		adao.insertAnswer(dto);
		
		model.setViewName("redirect:content?num="+dto.getNum()+"&currentPage="+currentPage);
		
		return model;
	}
	
	//list출력은 BoardContentController에서 한다
}

content.jsp

content.jsp 안에 list+insert 폼

			<!-- 댓글 -->
			<tr>
				<td>
					<div id="answer">
						<b>댓글: ${acount }</b><br><br>
						<c:forEach var="a" items="${alist }">
							${a.nickname }:${a.content }&nbsp;&nbsp;
							<span style="color: gray; font-size: 0.9em">
								<fmt:formatDate value="${a.writeday }" pattern="yyyy-MM-dd HH:mm"/>
							</span>
							&nbsp;&nbsp;
							<i class="adel bi bi-file-minus" style="cursor: pointer;" idx="${a.idx }"></i>
							<br>
						</c:forEach>
					</div>
					
					<form action="ainsert" method="post" style="width: 600px;">
						<input type="hidden" name="num" value="${dto.num }">
						<input type="hidden" name="currentPage" value="${currentPage }">
						
						<div class="d-inline-flex">
							<b>닉네임: </b>
							<input type="text" name="nickname" class="form-control"
							style="width: 120px;" required="required">
							
							<b>비밀번호: </b>
							<input type="password" name="pass" class="form-control"
							style="width: 120px;" required="required">
						</div>
						<br>
						<div class="d-inline-flex">
							<input type="text" name="content" class="form-control"
							style="width: 500px;" placeholder="댓글내용을 입력해주세요">
							<button type="submit" class="btn btn-outline-info">확인</button>
						</div>
					</form>
				</td>
			</tr>

list

answerMapper.xml

	<select id="SelectNumOfReanswer" parameterType="int" resultType="adto">
		select * from reanswer where num=#{num} order by idx asc
	</select>

AnswerDaoInter.java

	public List<AnswerDto> getAnswerList(int num);

AnswerDao.java

	@Override
	public List<AnswerDto> getAnswerList(int num) {
		// TODO Auto-generated method stub
		return session.selectList("SelectNumOfReanswer", num);
	}

BoardListController.jsp

기존 list controller에 댓글 dao 와 list 출력 추가하면 된다

  • AnswerDao adao
	//댓글 갯수 출력용
	@Autowired
	AnswerDao adao;
  • 댓글 list 추가
    dto에 값 넣어준다(adao의 getAnswerList에서 d의 넘값에 해당하는 size를)
		//list의 각 글에 댓글갯수 표시
		for(BoardDto d:list)
		{
			d.setAcount(adao.getAnswerList(d.getNum()).size()); // dto에 값 넣어준다(adao의 getAnswerList에서 d의 넘값에 해당하는 size를)
		}

-> list 안에서 값을 가져와 dto에 만들어준 acount값에 넣어준다

  • BoardListController.java
package board.data.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import answer.data.AnswerDao;
import spring.mvc.reboard.BoardDao;
import spring.mvc.reboard.BoardDto;

@Controller
public class BoardListController {

	@Autowired
	BoardDao dao;
	
	//댓글 갯수 출력용
	@Autowired
	AnswerDao adao;
	
	@GetMapping("/board/list")
	public ModelAndView list(
			@RequestParam(value = "currentPage",defaultValue = "1") int currentPage)
	{
		ModelAndView model=new ModelAndView();
		
		//페이징 처리에 필요한 변수 선언
		int totalCount=dao.getTotalCount();
		int totalPage; //총 페이지수
		int startPage; //각블럭에서 보여질 시작페이지
		int endPage; //각블럭에서 보여질 끝페이지
		int startNum; //db에서 가져올 글의 시작번호(mysql은 첫글이 0,오라클은 1)
		int perPage=10; //한페이지당 보여질 글의 갯수
		int perBlock=5; //한블럭당 보여질 페이지 개수


		     
		     
		//총페이지수 구하기
		//총글의 갯수/한페이지당 보여질 개수로 나눔(7/5=1)
		//나머지가 1이라도 있으면 무조건 1페이지 추가(1+1=2페이지가 필요)
		  	totalPage=totalCount/perPage+(totalCount%perPage==0?0:1);
		 
		//각블럭당 보여야할 시작페이지
		//perBlock=5일경우는 현재페이지 1~5 시작:1 끝:5
		//현재페이지 13  시작:11  끝:15
		  	startPage=(currentPage-1)/perBlock*perBlock+1;
		     
		  	endPage=startPage+perBlock-1;
		    
		// 총페이지가 23일경우 마지막블럭은 25가아니라 23이다   
		      if(endPage>totalPage)
		        	endPage=totalPage;
		     
		//각페이지에서 보여질 시작번호
		//1페이지: 0,2페이지:5 3페이지:10....
		startNum=(currentPage-1)*perPage;
			
		
		//각 페이지에서 필요한 게시글 가져오기
		List<BoardDto> list=dao.getPagingList(startNum, perPage);
		
		
		
		//list의 각 글에 댓글갯수 표시
		for(BoardDto d:list)
		{
			d.setAcount(adao.getAnswerList(d.getNum()).size()); // dto에 값 넣어준다(adao의 getAnswerList에서 d의 넘값에 해당하는 size를)
		}
		
		
		
		
		
		//각 페이지에 출력할 시작번호
		int no=totalCount-(currentPage-1)*perPage;
		
		
		
		model.addObject("totalCount", totalCount);
		
		//이곳에서 댓글 사이즈가 들어가기 때문에 따로 추가할 필요 없음
		//애초에 list에서 댓글갯수를 구해서 BoardDto에 넣었기 때문에
		model.addObject("list", list);
		model.addObject("startPage", startPage);
		model.addObject("endPage", endPage);
		model.addObject("totalPage", totalPage);
		model.addObject("no", no);
		model.addObject("currentPage", currentPage);
		
		

		model.setViewName("reboard/boardlist");
		
		return model;
	}

}

content.jsp

댓글 list출력

<div id="answer">
	<b>댓글: ${acount }</b><br><br>
	<c:forEach var="a" items="${alist }">
		${a.nickname }:${a.content }&nbsp;&nbsp;
		<span style="color: gray; font-size: 0.9em">
			<fmt:formatDate value="${a.writeday }" pattern="yyyy-MM-dd HH:mm"/>
		</span>
		&nbsp;&nbsp;
		<i class="adel bi bi-file-minus" style="cursor: pointer;" idx="${a.idx }"></i>
		<br>
	</c:forEach>
</div>

delete

answerMapper.xml

	<!-- 댓글 삭제 -->
	<select id="PassCheckPassOfAnswer" parameterType="HashMap" resultType="int">
		select count(*) from reanswer where idx=#{idx} and pass=#{pass}
	</select>
	
	<delete id="deleteOfReanswer" parameterType="int">
		delete from reanswer where idx=#{idx}
	</delete>

AnswerDaoInter.java

	public int getCheckPass(int idx,String pass);
	public void deleteAnswer(int idx);

AnswerDao.java

	@Override
	public int getCheckPass(int idx, String pass) {
		// TODO Auto-generated method stub
		Map<String, Object> map=new HashMap<String, Object>();
		
		map.put("idx", idx);
		map.put("pass", pass);
		
		return session.selectOne("PassCheckPassOfAnswer", map);
	}

	@Override
	public void deleteAnswer(int idx) {
		// TODO Auto-generated method stub
		session.delete("deleteOfReanswer", idx);
	}

AnswerRestController.java

json값으로 변환해서 넘어가는건 check값만 넘어간다
idx값과 pass값은 content에서 ajax로 값 넘어옴

json변환 확인하고 싶으면
board/adelete?idx=&pass=
*은 db에 있는 값 확인해서 넣는다
-> 맞으면 {"check":1} / 틀리면 {"check":0}으로 나옴

package answer.data;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

//pom.xml에 json repository추가
@RestController
public class AnswerRestController {

	@Autowired
	AnswerDao adao;

	@GetMapping("/board/adelete")
	public Map<String, Integer> answerdelete(@RequestParam int idx,
			@RequestParam String pass)
	{
		int check=adao.getCheckPass(idx, pass);
		
		if(check==1)
		{
			adao.deleteAnswer(idx);
		}
		
		Map<String, Integer> map=new HashMap<String, Integer>();
		
		map.put("check", check); //{"check":1}
		
		return map;
	}
}

content.jsp

idx 값 심기

<i class="adel bi bi-file-minus" style="cursor: pointer;" idx="${a.idx }"></i>

ajax

ajax의 mapping url은 controller에서 정한 mapping주소 넣어주면된다
ajax의 넘겨주는 값은 i태그에서 가져온 idx값과 prompt로 입력한 pass값만 넘겨준다

<script type="text/javascript">
	    $("i.adel").click(function() {
	        var idx = $(this).attr("idx");
	        var pass = prompt("비밀번호 입력");
	        
	        if(pass==null)
	        	return;
	        else{
	            $.ajax({
	                type: "get",
	                url: "adelete", //Controller에서 정한 mapping주소 넣어주면 된다
	                data: { "idx": idx,"pass":pass}, //이 값들을 AnswerRestController로 보냄 그 값을 dao의 check로 확인함 Controller에서 json형태로 변환되는건 check변수 하나
	                dataType: "json",
	                success: function(res) {
	                	if(res.check==0)
	                	{
	                		alert("비밀번호가 맞지 않습니다");
	                	}
	                	else{
	                		alert("댓글을 삭제합니다");
	                    	location.reload();
	                	}
	                },
	                error: function() {
	                    alert("오류가 발생했습니다.");
	                }
	            });
	        }
	    });
	</script>
profile
백엔드 개발자로서 성장해 나가는 성현이의 블로그~

0개의 댓글