ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 회원가입, 로그인, 게시판 백엔드 실습( 댓글 리스트 , pagenation )
    Spring 2023. 4. 6. 15:03

    댓글 리스트 , pagenation 작성하기

     : get 방식으로 데이터베이스에 있는 데이터를 조회하고 JavaScript로 데이터를 브라우저에 나타낼 것이다.

     

    1) JavaScript 작성

    $(document).ready(function(){
    	var board_noValue=$("input[name='board_no']").val();
    	var pageValue=1;
        
    	// detail.jsp가 시작되자마자 댓글목록리스트(list) 함수를 호출
    	list({board_no:board_noValue,page:pageValue});
    	
        // 페이지네이션의 페이지를 클릭하면 해당 페이지의 댓글을 호출
    	$("#replyPage").on("click","li a",function(e){
    		alert("aaa")
    		e.preventDefault();
    		var board_noValue=$("input[name='board_no']").val();
    		var pageValue = $(this).attr("href");
            
    		list({board_no:board_noValue,page:pageValue});
    	})
    })
    
    // list 함수 호출
    function list(param){
    	var board_no = param.board_no;
    	var page = param.page;
    	
    	$.getJSON("/replies/"+board_no+"/"+page+".json",function(data){
    		
    		var str="";
    		
    		for(var i=0;i<data.list.length;i++){
    			str+="<li>"+data.list[i].id+"</li>"
    			str+="<li><textarea id='replycontent"+data.list[i].rno+"'>"+data.list[i].content+"</textarea></li>"
    			str+="<li>"
    			str+="<input class='update' type='button' value='수정' data-rno="+data.list[i].rno+">"
    			str+="<input class='remove' type='button' value='삭제' data-rno="+data.list[i].rno+">"
    			str+="</li>"
    		}
    		
    		$("#replyUL").html(str);
    		
            // 페이지네이션 함수 호출
    		showReplyPage(data.replycnt,page);
    	});
    }
    
    // 페이지네이션 호출
    function showReplyPage(replycnt,pageNum){
    	
    	var endNum = Math.ceil(pageNum/10.0)*10;
    	var startNum = endNum-9
    	
    	var prev=startNum !=1;
    	var next=false;
    	
    	if(endNum * 10 >= replycnt){
    		endNum = Math.ceil(replycnt/10.0)
    	}
    	if(endNum * 10 < replycnt){
    		next=true;
    	}
        
    	var str="<ul>";
    	
    	if(prev){
    		str+="<li><a href='"+(startNum-1)+"'>Previous</a></li>";
    	}
    	
    	for(var i=startNum ; i<=endNum ; i++){
    		str+="<li><a href='"+i+"'>"+i+"</a></li>"
    	}
    	
    	if(next){
    		str+="<li><a href='"+(endNum+1)+"'>Next</a></li>";
    	}
        
    	str+="</ul><div>"
    	$("#replyPage").html(str);
    }

     - 처음 렌더링이 시작 될 때 현재 게시글 번호인 board_no를 읽어오고 pageValue를 1로 저장하고 list 함수를 호출한다.

     

     - list 함수는 JSON 형태로 해당 게시물에 대한 정보를 호출하고, 호출한 데이터를 for 문을 활용해서 HTML 문법으로 작성한다.

     

     - 작성된 HTML 문법을 다음과 같은 형태로 jsp파일 내부의 원하는 위치에 배치한다.

    $("#replyUL").html(str);

     

     - 페이지네이션은 a 태그로 작성되었기 때문에, 클릭 이벤트로 선언할 때 e.preventDefault를 선언해 a 태그의 이동 기능을 제한한다.

    또한 a 태그의 href 의 속성을 pageValue에 저장하고 list를 호출함으로서 a 태그 클릭 시 해당 page에 속하는 댓글들을 불러온다.

     

     - 페이지네이션의 호출은 현재 페이지 넘버를 올림함으로서 endNum을 정의하고 startNum = endNum-9를 하는 것으로

    나타날 페이지의 숫자의 일의 자릿 수가 1 ~ 0 까지 배치될 수 있도록 한다.

     

     - endNum * 10 과 replycnt ( 댓글의 총 갯수 ) 를 비교해서

    댓글의 총 갯수가 적을 경우 next 버튼이 생성되지 않도록 next = false인 상태로 두고

    댓글의 총 갯수가 많을 경우 next 버튼이 생성되도록 next = true 선언한다.

     

     - 만일 페이지의 총 갯수가 10개 이하라면, startNum 은 항상 1이기 때문에, 이전 버튼을 생성하지 않고

    총 갯수가 11개 이상이라면, startNum != 1 이 참이기 때문엥 이전 버튼을 생성한다.

     

     

    CriteriaVO.java는 다음과 같다

    public class CriteriaVO {
    	private int pageNum;
    	private int amount;
    	private String keyword;
    	private String type;
    	
    	//생성자
    	public CriteriaVO() {
    		this(1,10);
    	}
    	public CriteriaVO(int pageNum, int amount) {
    		this.pageNum = pageNum;
    		this.amount = amount;
    	}
        
        필드의 getter 와 setter
        
    }

     

    2) Controller 작성

    @Controller
    public class ReplyController {
    	
    	@Autowired
    	ReplyService rs;
    		// 댓글 목록 리스트
    		@RequestMapping(value = "/replies/{board_no}/{page}", method = RequestMethod.GET)
    		public ResponseEntity <ReplyPageVO> getList(@PathVariable("page") int page,@PathVariable("board_no") int board_no){
    			CriteriaVO cri = new CriteriaVO(page,10);
    			return new ResponseEntity<>(rs.list(cri, board_no),HttpStatus.OK);
    		}
    }

     - /replies/{board_no}/{page} 으로 부터 Json 데이터를 호출하고 page , board_no 파라미터를 매개변수로 보낸다.

    이 파라미터는 (현재 페이지-1) * 10 ~ (현재 페이지) * 10 사이의 pno 데이터들을 내림차순으로 호출하는데 사용된다.

     

     - CriteriaVO 는 기본적으로 (1,10)으로 생성자가 선언되어 있지만, (page,10)으로 다시 생성해서 호출한다.

     

    3) Service , ServiceImpl 작성

    public interface ReplyService {
    	// 댓글 목록 리스트를 위한 설계
    	//public ArrayList<ReplyVO> list(int bno);
    	public ReplyPageVO list(CriteriaVO cri, int board_no);
    }
    @Service
    public class ReplyServiceImpl implements ReplyService{
    
    	@Autowired
    	ReplyMapper rm;
    
    	// 댓글 목록 리스트를 위한 구현
    	public ReplyPageVO list(CriteriaVO cri,int board_no){
    		return new ReplyPageVO(rm.rpycnt(board_no),rm.list(cri,board_no));
    	}
    }

     - ServiceImpl에서 전체 댓글 갯수를 읽어오는 rm.rpycnt()와, 댓글의 정보를 가져오는 rm.list() 함수를 실행한다.

     

    4) Mapper , Mapper.xml

    public interface ReplyMapper {
    		// 댓글 목록리스트를 위한 구현
    		//public ArrayList<ReplyVO> list(int bno);
    		public ArrayList<ReplyVO> list(@Param("cri") CriteriaVO cri,@Param("board_no") int board_no);
    }
    <?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 namespace="hjm.portfolio.mapper.ReplyMapper">
    
    	<select id="list" resultType="hjm.portfolio.model.ReplyVO">
    		select *
    		from(
    			select @rownum:=@rownum+1 rownum, b.*
    			from port_reply b, (select @rownum:=0) as tmp
    		    where board_no=#{board_no}
    			order by board_no desc
    		) as boardlist
    		<![CDATA[
    		where rownum > (#{cri.pageNum}-1)*#{cri.amount} and rownum <= #{cri.pageNum}*#{cri.amount}
    		]]>
    	</select>
    	<select id="rpycnt" resultType="int">
    		select count(*) from port_reply where board_no=#{board_no}
    	</select>
        
    </mapper>

    ** Mapper 를 통해 mySql 에서 사용할 변수가 여러개일 경우 @param("변수명") 을 꼭 선언해줘야한다.

     

     - Mapper.xml의 list는 현재 페이지를 기준으로 ( 현재페이지 -1 ) * 10 ~ ( 현재페이지 ) * 10 사이의 rno를 가진 데이터를 호출한다.

     

     - rpycnt는 현재 게시글의 board_no와 같은 값을 가진 모든 댓글 데이터의 갯수를 호출한다.

     

    5) 결과

     

Designed by Tistory.