프로젝트/G.O.A.T(여행 스케줄러)

게시판 무한댓글(대댓글) 드디어 해결!!!!

찌서니 2022. 1. 14. 10:30
🔔 22월 01월 13일
✔ 무한 댓글 로직 다시 생각
✔ sql문 다시 작성
✔ 댓글의 대댓글
✔ re댓글도 로그인해야지만 쓸수있게
✔ 자기가 남긴 re댓글만 수정/삭제
✔ 여행게시판 리스트

드디어!! 대댓글 해결했다!!! 감격!!

실습했던 자료가 있었는데,, 이해하는데 시간이 오래 걸렸고

로직을 잘못 생각했던게 문제가 컸음ㅠㅠ

 

대댓글 로직

REF는 댓글끼리 묶는 기능, RE_STEP으로 순서를 나타내고, RE_LEVEL은 들여쓰기를 나타낸다

이거 로직을 생각하는게 힘들었음ㅜ 저번 글로 하면 sql문 정렬이 안됨

 

 

<대댓글 로직도 설명>

1단계

처음 게시글에 댓글을 달면 REF는 1이고, RE_STEP과 RE_LEVEL은 0으로 세팅해준다.

REF는 댓글의 번호(nor_num)와 같게 했기 때문에 두번째 댓글은 REF가 2가 아닐수 있다.

 

2단계

댓글끼리 묶어야 되기 때문에 댓글에 댓글을 달게되면,

REF는 1로 똑같고, RE_STEP은 +1이 되고, RE_LEVEL도 +1이 된다.

새로운 댓글을 달면 어떻게 될까?

 

3단계

새로운 댓글을 달았기 때문에 REF는 댓글번호에서 가져오고,

새로운 묶음(?)이기 때문에 RE_STEP과 RE_LEVEL은 다시 0으로 세팅된다.

여기서 REF=1에 댓글을 달면 어떻게 될까?

 

4단계

REF:1, RE_STEP:0, RE_LEVEL:0에 댓글을 달았기 때문에

REF는 묶음이기 때문에 부모댓글과 같고, RE_STEP(순서)는 +1이 되고,

댓글의 댓글이기 때문에 들여쓰기는 한칸만 들어가면 되기 때문에

REF:1, RE_STEP:1, RE_LEVEL:1과 RE_LEVEL이 똑같다.

이 다음 로직을 이해하는데 엄청 오래 걸렸는데,

REF:1, RE_STEP:1, RE_LEVEL:1에 댓글을 달면 어떻게 될까?

이 로직이 댓글의 대댓글(무한댓글)이었다.

 

5-1단계

여기부분은 쪼개서 설명하겠음!

REF:1, RE_STEP:1, RE_LEVEL:1에 댓글을 달았지만,

제일 조상의 REF는 1이기 때문에 댓글 달은 nor_num을 가져오는게 아니라

제일 조상의 nor_num을 가져와야 된다.

그리고 댓글 달은 RE_STEP에 +1을 해주고,

RE_LEVEL도 한칸 더 들어가야되기 때문에 +1을 해준다.

 

5-2단계

원래 기존에 있던 REF:1, RE_STEP:2, RE_LEVEL:1에서

RE_STEP을 +1을 해줘야된다.

왜냐면 대댓글이 그 사이에 꼈기 때문에, 지금은 댓글이 한 개만 있었지만,

만약 뒤에 RE_STEP: 2,3,4가 있었다면 -> 3,4,5로

댓글을 달은 RE_STEP보다 큰 RE_STEP은 모두 +1을 해주면 뒤로 밀려남

RE_LEVEL은 들여쓰기이기 때문에 따로 변경될 사항은 없다.

 

 

 

<오라클 실행>

여기서 첫번째 댓글에 두번째 댓글을 달면?

 

RE_STEP은 +1이 되었고, RE_LEVEL은 1로 똑같은걸 알수 있다.

이제 1-1-1의 댓글을 남겨보면???

 

1-1-1의 RE_STEP은 1-1의 RE_STEP에서 +1이 돼서 2가되었고,

RE_LEVEL도 +1이 돼서 2가 되었고,

기존에 있던 RE_STEP은 다 +1이 되었다.

 

 

내가 헷갈렸던 부분이 처음에 실습했을 때는 답글이어서

InsertForm과 Insert를 컨트롤러에서 두개로 나눠서 했는데,

댓글이기 때문에 페이지 넘김을 안하려고 ajax로 띄워서

rInsert 하나의 컨트롤러로 활용하려다 보니 어디서 값을 가져오고

보내야 되는지 부분에서 많이 막혔다ㅜ

밑에는 컨트롤러와 jsp 첨부!!!

 

@RequestMapping("notice/rInsert")
	public String rInsert(NoticeReply nr, HttpSession session) {
		int m_num = (Integer) session.getAttribute("m_num");
		int number = nrs.maxNum(); // 새 댓글 번호 생성, ref는 nor_num이랑 똑같음
		
		// ref 답변글끼리 뭉칠때, re_step 답변글 순서, re_level 들여쓰기
		int nor_re_step = 0, nor_re_level = 0; // 첫번째 댓글은 0,0 기본 세팅
		int no_num = nr.getNo_num(); // 어떤 글에 댓글 썼는지 번호 가져오기(jsp에서 보냈음)
		int nor_num = nr.getNor_num(); // 어떤 댓글에 댓글 남긴건지(jsp에서 보냈음)
		String nor_content = nr.getNor_content(); // 댓글내용(jsp에서 보냈음)
		
		if(nor_num != 0) { // 댓글에 댓글을 달 때
			NoticeReply nr1 = nrs.select(nor_num); // 읽어온 댓글의 re_step과 re_level을 알기 위해서
			if(nr1.getNor_re_step() == 0 && nr1.getNor_re_level() == 0) {
				nr.setNor_ref(nor_num); // 대댓글끼리 뭉치기위해, 부모댓글의 댓글번호로 ref 세팅
				int maxStep = nrs.maxStep(nr1.getNor_ref()); // 댓글중에서 새로운 댓글 달때 맨 밑으로 가기 위해서
				nr.setNor_re_step(maxStep);
				nr.setNor_re_level(nr1.getNor_re_level() + 1);
			}
			else { // 댓글의 대댓글을 달 때
				nr.setNor_ref(nr1.getNor_ref()); // 대댓글끼리 뭉치기위해, 부모댓글의 댓글번호로 ref 세팅
				nr.setNor_re_step(nr1.getNor_re_step());
				// 새로운 댓글은 사이에 껴야되기 때문에
				nrs.updateStep(nr); // 글을 읽고 ref가 같고 re_step이 읽은 글의 re_step보다 크면 그글의 re_step + 1
				
				nr.setNor_ref(nr1.getNor_ref());
				nr.setNor_re_step(nr1.getNor_re_step() + 1);   // 댓글(읽은값)단 re_step보다 1 증가
				nr.setNor_re_level(nr1.getNor_re_level() + 1); // 댓글(읽은값)단 re_level보다 1 증가
			}
		} else {
			nr.setNor_ref(number);
			nr.setNor_re_step(nor_re_step); // 기본 댓글에는 0세팅
			nr.setNor_re_level(nor_re_level); //     "
		}

		nr.setNor_content(nor_content);
		nr.setNor_num(number);
		nr.setNo_num(no_num);
		nr.setM_num(m_num);

		nrs.insert(nr);
		
	//  결과를 jsp로 보내지 않고 controller내에서 찾을 때 : redirect 또는 forward
		return "redirect:/notice/noticeReplyList.do?no_num="+nr.getNo_num();
	}

다른건 안 긴데,,, 이 코드는 엄청 길게됐다.

처음 댓글 남김/ 댓글의 댓글/ 댓글의 대댓글 이렇게 3가지로 분류했기 때문이다.

어디에서 데이터를 가져오고 보내는지 몰라서, 주석이 많을수 밖에 없다...

 

 

function rr(nor_num, no_num) {
		var nor_content = frm2.nor_content.value;
		alert(nor_content);
		if(frm2.nor_content.value == "") {
			alert("댓글을 입력해주세요");
			frm2.nor_content.focus();
			return false;
		}

		$.post('rInsert.do?nor_num='+nor_num+"&no_num="+no_num+"&nor_content="+nor_content, function(data) {
			alert("대댓글이 작성 되었습니다");	
			$('#nrListDisp').html(data);
			frm2.nor_content.value="";  // 작성했던 댓글 지우기
		});
	}
function rpInsert(nor_num, no_num) {
		if (${empty id && empty admin}) {
			alert("댓글은 로그인후 작성할 수 있습니다.");
			location.href="${path}/member/loginForm.do";		
		}
//		댓글을 읽어서 textarea에 넣어서 수정 가능하게 만들어야 한다
//		input, textarea에 있는 데이터를 읽을 때는 jquery val()
//		td등 일반 태그에 있는 데이터를 읽을때는 jquery에서는 text()로 읽는다
		$('.reply_'+nor_num).html("<form action='' id='frm2' name='frm2'>"+
			"<input type='hidden' name='nor_num' value='"+nor_num+"'>"+
			"<table> &nbsp;&nbsp;&nbsp;"+
			"<tr><td><textarea rows='3' cols='100' name='nor_content'></textarea> &nbsp;&nbsp;"+ 
			"<input type='button' onclick='rr("+nor_num+","+no_num+")' value='등록'>"+
			"<input type='button' onclick='lst("+no_num+")' value='취소'></td></tr></table>");
}

진짜 스크립트 부분도 너무 아찔했음...

"와 '도 구별해야되고, +도 써줘야되고 도대체 이게 맞아?

이러고.. 스크립트는 오류도 제대로 안 보여주고 휴,,,

 

 

maxNum -> 새로운 댓글을 달때 nor_num을 중복되지않고 순차적으로 주기 위해 사용

nor_num이 0이면 0에다 +1을 해주고, 값이 있다면 max값에다 +1해줘~

 

maxStep -> 댓글의 댓글에 달때, nor_re_step이 0이면 +1해주고, 값이 있다면 max값에다 +1해줘~~

 

updateStep -> 댓글의 대댓글(무한댓글) 달때, 우선 nor_ref가 같은 댓글(묶음)과 nor_re_step이 선택한(어디에 댓글 달지) nor_re_step보다 큰거는 nor_re_step을 다 +1해줘~ (중간에 껴야돼서)

이 부분은 이해하는데도 엄청 오래 걸렸고, nor_re_step=#{nor_re_step}+1로 했다가

모든값이 다 똑같이 바뀌길래 왜지? 이랬는데 내가 쓴 sql을 해석하면

들어온 nor_re_step을 +1한 값을 nor_re_step으로 다 바꿔죠!

하지만 내가 하고 싶었던거는 원래있는 nor_re_step+1해서 nor_re_step에 저장해줘~였다.

 

 

이걸로 드디어 대댓글 끝!!!!!!!

이제는 여행 게시판 해봅시다~

'프로젝트 > G.O.A.T(여행 스케줄러)' 카테고리의 다른 글

여행게시판 대댓글 추가  (1) 2022.01.18
여행 게시판 해결! ckEditor4  (0) 2022.01.16
게시판 대댓글(무한댓글) 해결안됨  (0) 2022.01.13
3주차 PPT  (0) 2022.01.13
공지사항 댓글  (0) 2022.01.11