Backend/Spring

[Spring] 댓글 목록 조회

Deeb 2022. 1. 19. 17:36

댓글 조회

샘플데이터 넣은 글에 넣은 샘플 데이터 조회하기!

 

 

 

비동기 - 동시에 일을처리

동기 - 순차적 처리

 

contextPath : /fin

// JSON: JS 객체 형태의 문자열( 모든 프로그램에서 사용 가능)
// 응답 데이터 형식이 JSON 형식임을 알려주어 자동으로 JS객체로 변환시켜준다 

-> 반환된 값이 Object로 반환된다.


ReplyController

 

@RestController // 요청 시 값만 반환되는 컨트롤러 @Controller + @ResponseBody
@RequestMapping("/reply/*")
public class ReplyController {
	
	@Autowired
	private ReplyService service;
    
    // 댓글 목록 조회
	@RequestMapping(value="select", method = RequestMethod.GET)
	public String selectList(int boardNo) {
							
		List<Reply> rList = service.selectList(boardNo);
		
		return new Gson().toJson(rList);
	}
    
}

 

매개변수

int boardNo : RequestParam 생략 형식

(ajax 코드의 data 속성에 작성된 key값을 매개변수로 보내준다. )


조회된 rList를 JSON형식으로 변경
-> 직접 변경 / JSONSimple 라이브러리 / GSON 라이브러리 
이 중에서 GSON 라이브러리 사용!

new Gson().toJson(rList) : object를 JSON형태로 변환


 

ReplyController에서 GSON 라이브러리 사용하기때문에 POM.XML에 GSON 라이브러리 추가 

 

GSON: JSON의 길어지는 코드를 간결하게 하기 위해 사용되는 라이브러리

 

라이브러리 모아둔 곳에 추가

 

 

 

@RequestMapping(value="select", method = RequestMethod.GET)
	public String selectList(int boardNo) {
							// ajax 코드의 data 속성에 작성된 key값을 매개변수로 보내준다. 
		
		List<Reply> rList = service.selectList(boardNo);
		
		// 조회된 rList를 JSON형식으로 변경
		//-> 직접 변경 / JSONSimple 라이브러리 / GSON 라이브러리 
		// GSON 라이브러리 사용!
		
		// POM.XML가서 라이브러리 추가하고오기
		// new Gson().toJson(rList) : object를 JSON형태로 변환
		
		return new Gson().toJson(rList);
	}

 

reply.js

-ajax진행

// 댓글 목록 조회
function selectReplyList(){

// 비동기 통신(ajax)를 이용해서 JSON 형태로 댓글 목록 조회 및 출력
$.ajax({
    url : contextPath + "/reply/select",
    data : {"boardNo" : boardNo}, // 현재 게시글 번호
    type : "get",
    dataType : "JSON",  // JSON: JS 객체 형태의 문자열( 모든 프로그램에서 사용 가능)
                        // 응답 데이터 형식이 JSON 형식임을 알려주어 자동으로 JS객체로 변환시켜준다 

    success : function(rList){
        console.log(rList);
        // 댓글 목록을 요소로 만들어서 화면에 출력

        // 기존 댓글 영역 내용 삭제 
        // $("#replyListArea").html("");  // 내용을 지워라
        $("#replyListArea").empty(); // 내용을 비워라(이게 더 빠름)

        // rList 요소를 순차적으로 반복 접근
        // reply에서 하나씩 꺼내오면 그게 reply니깐 그걸로 적음 
        $.each(rList, function(index, reply){

            //const li = $("<li>").addClass("reply-row");
            const li = $('<li class="reply-row">');

            // 자식 댓글인 경우 li요소에 클래스 추가
            // 부모댓글이 0이 아닐때라는 조건을 한 이유 : db에서는 null, java에서는 int로 기본값 0이 들어간다
            if (reply.parentReplyNo != 0) li.addClass("child-reply");

            const div = $('<div>');

            const rWriter = $('<p class="rWriter">').text(reply.memberName);
            const rDate = $('<p class="rDate">').text('작성일 : ' + reply.replyCreateDate);
            // p 태그에 작성된 내용들을
            // div에 자식으로 rWriter, rDate 추가
            div.append(rWriter, rDate);

            // 댓글 내용
            // 내용은 html로 하는 이유: <br> 태그를 태그 자체로 인식해서 출력해야하니깐
            const rContent = $('<p class="rContent">').html(reply.replyContent);

            li.append(div, rContent);
            // 위의 div와 내용을 li에 추가 


            // 1. 버튼 영역 요소 생성 
            const replyBtnArea = $('<div class="replyBtnArea">');

            // 로그인 되어있다면  
            if (loginMemberNo != "") {
                // 버튼 생성 : css가 들어있는 클래스를 추가, 내용 추가
                const childReply = $("<button>").addClass("btn btn-primary btn-sm ml-1").text("대댓글");

                //버튼 클릭 시 대댓글 작성 영역을 출력하는 함수 호출 
                // reply.replyNo : 현재 댓글 번호, 대댓글의 부모 번호 댓글 번호 (parentReplyNo))
                // this : 이벤트가 발생한 요소 자체 
                //      - 해당요소를 기준점으로 하여 
                //          parent(), children(), prev(), next() 등의 순회(탐색)메서드
                //          append(), after(), before() 등의 요소 삽입 메서드를 작성할 예정

                // 화면이 계속 바뀌니깐 언제 어느 요소를 넣을지 모르니 기준점을 기준으로 탐색해서 만든다
                childReply.attr("onclick", "showInsertReply(" + reply.replyNo + ", this)");

                // 버튼 영역에 추가
                replyBtnArea.append(childReply);
            }


            // 댓글 작성자 == 로그인 멤버 -> 버튼 영역 생성
            if (reply.memberNo == loginMemberNo) { // 자신이 쓴 댓글이니 수정, 삭제 가능

                // 수정버튼 생성
                const showUpdate = $('<button>').addClass('btn btn-primary btn-sm ml-1').text('수정');
                showUpdate.attr("onclick", "showUpdateReply(" + reply.replyNo + ", this)");

                // 삭제 버튼 생성
                const deleteReply = $('<button>').addClass('btn btn-primary btn-sm ml-1').text('삭제');
                deleteReply.attr("onclick", "deleteReply(" + reply.replyNo + ")");

                replyBtnArea.append(showUpdate, deleteReply);
            }


            li.append(replyBtnArea);

            // ul태그에  li 요소를 하나씩 마지막 자식으로 삽입 
            $("#replyListArea").append(li);


        });



    }, error : function(req, status, error){
        console.log("댓글 목록 조회 실패");
        console.log("req.responseText");
    }


});

 

 


BoardController

- 상세조회 메서드에 replyservice 호출 

// 게시글 상세 조회
@RequestMapping("view/{boardNo}")
public String selectBoard(@PathVariable("boardNo") int boardNo,
        @RequestParam(value = "cp", required = false, defaultValue = "1") int cp, // 파라미터로 cp값을 받아오는데 없으면 1
        Model model, RedirectAttributes ra
        /*@ModelAttribute("loginMember") Member loginMember*/, HttpSession session) { 

        // @SessionAttributes
        // 1) Model.addAttribute(K,V) 수행 시 K가 일치하는 값을 Requst -> Session Scope로 이동
        // 2) Model.addAttribute(K,V)  Session으로 이동한 값을 얻어와 -> @ModelAttribute("K")에 전달

    int memberNo = 0;

    // session에 로그인 멤버가 있을 경우
    if(session.getAttribute("loginMember") != null) {
        memberNo = ( (Member)session.getAttribute("loginMember")).getMemberNo(); 
        //여기서 왜 값을 loginMember로 받아????
    }

    // 게시글 조회 Service 호출 (작성자가 보면 조회수 증가하지 않기위해 회원번호를보낸다)
    Board board = service.selectBoard(boardNo, memberNo);

    String path = null;

    if(board != null) {// 조회 성공 : 값이 있다

        // 댓글 목록 조회 Service 호출
        List<Reply> rList = replyService.selectList(boardNo);

        model.addAttribute("rList", rList);
        model.addAttribute("board", board); // requestScope로 전달
        path="board/boardView"; // forward

    } else { // 조회 실패

        Util.swalSetMessage("해당 글이 존재하지 않습니다", null, "info", ra);
        path = "redirect:../list";			
    }

    return path;
}

ReplyService

/** 댓글 목록 조회
 * @param boardNo
 * @return rList
 */
List<Reply> selectList(int boardNo);

ReplyService

// 댓글 목록 조회 
@Override
public List<Reply> selectList(int boardNo) {
    return dao.selectList(boardNo);
}

ReplyDAO

/** 댓글 목록 조회
 * @param boardNo
 * @return rList
 */
public List<Reply> selectList(int boardNo) {
    return sqlSession.selectList("replyMapper.selectList", boardNo); // boardNo를 파라미터로 넘긴다 
}

reply-mapper

<!-- 댓글 목록 조회 
parameterType="_int" 생략되어있다-->
<select id="selectList" resultMap="reply_rm">
    SELECT LEVEL, R.*
    FROM (SELECT REPLY_NO, REPLY_CONTENT, TO_CHAR(REPLY_CREATE_DT, 'YYYY"년"
        MM"월" DD"일" HH24"시" MI"분" SS"초"') REPLY_CREATE_DT,
        BOARD_NO, REPLY.STATUS_CD, PARENT_REPLY_NO, MEMBER_NO, MEMBER_NM
        FROM REPLY
        JOIN MEMBER USING(MEMBER_NO)
        WHERE BOARD_NO = #{boardNo}
        AND REPLY.STATUS_CD = 1) R

    START WITH PARENT_REPLY_NO IS NULL
    CONNECT BY PRIOR REPLY_NO = PARENT_REPLY_NO
    ORDER SIBLINGS BY REPLY_NO
</select>

 

 

 

반응형