오늘 한 일

프로젝트

  • 통합 로그인 과정 캡처 ppt로 제작

게시판 프로젝트

  • 답글 정렬 연습 (숫자id, 문자id)
  • 답글 정렬 테이블 변경, 쿼리 작성
  • vo, mapper, controller, jsp 등 수정
  • xml, mapper 변경사항 적용 안되는 에러 해결

답글 정렬 SQL 연습

현재 문의사항 게시판은 기본적인 CRUD + 게시물 상세화면에서 정보 가져와 답글 등록 + 답글 등록/삭제 시 기존 게시물 상태변경까지 가능한 상태였다. 답글을 만드는건 좋은데, 목록 조회에서 기존게시물 사이사이에 답글이 달리게 하려면 현 테이블 구조로는 어렵다는 것을 깨닫고 방법을 검색해보았다.

내가 참고한 방법은 oracle의 계층 구조 쿼리를 사용하는 방법이다. 오라클의 START WITH, CONNECT BY, ORDER SIBILINGS BY를 사용했다.

예시 블로그에선 기준이 되는 게시물id, 부모 id 등이 전부 정수로 되어있었는데, 내 프로젝트는 id값이 전부 문자열이기도 하고 조회 쿼리도 복잡해서 먼저 정수id를 가진 테스트 테이블을 만들어서 연습해보았다.

1. 답글 정렬 연습 (숫자 id)

  • 목표 : 일반 게시물 1, 2, 3이 있고 각각의 답글 4, 5, 6 게시물이 있다. 게시물 목록 조회 시 최신 게시물이 가장 위에 오고, 게시물의 답글은 기존 게시물 바로 밑에 달린다.

ex)
3
----6
2
----5
1
----4

1. 계층 쿼리를 사용하기 위해 BOARD_ID, TITLE, PARENT_ID, GROUP_ID, LV 컬럼을 가진 테이블을 생성했다.

  • BOARD_ID : 게시물 ID, 게시물 고유 번호
  • TITLE : 게시물 제목. LV컬럼 값에 따라 들여쓰기 기능을 구현하기 위해 추가
  • PARENT_ID : 부모ID, 일반 게시물일 경우 0, 답글 게시물일 경우 부모의 BOARD_ID 저장
  • GROUP_ID : 그룹ID, 게시물 ORDER 기준이 됨. 일반 게시물일 경우 BOARD_ID, 답글 게시물일 경우 PARENT_ID 저장
  • LV : 게시물의 깊이 (level, depth) 저장. 깊이만큼 제목 앞에 들여쓰기하기 위해 추가
2. 더미 데이터 삽입

3. 조회 쿼리
/* ID = NUMBER */
SELECT board_id, LPAD(' ', 4*(lv-1)) || title title, parent_id, lv, group_id FROM TEST
START WITH parent_id=0
CONNECT BY PRIOR board_id=parent_id
ORDER SIBLINGS BY group_id desc;

2. 답글 정렬 연습 (문자열 id)

egov 프로젝트를 한다면 전자정부에서 제공하는 idgen을 사용하게 되는데, 문자열과 숫자 조합을 많이 사용한다. 그래서 id가 문자열이어도 정렬이 잘 될까 걱정이었는데, 문자열을 별도로 잘라서 숫자처리하지 않아도 정렬이 잘 되는 것을 확인했다.

1. 데이터

2. 쿼리
/* ID = VARCHAR */
SELECT board_id, LPAD(' ', 4*(lv-1)) || title title, parent_id, lv, group_id FROM TEST2
START WITH parent_id='TEST-000'
CONNECT BY PRIOR board_id=parent_id
ORDER SIBLINGS BY group_id desc;

실제 프로젝트에 적용

연습용 테이블에 비해 실제 프로젝트의 조회 쿼리는 굉장히 복잡하지만, 결국 필요한 컬럼과 코드는 동일해서 작성하기 어렵지 않았다.

  1. mapper.xml의 sql 쿼리 변경
  • column 추가 : 기존에 추가해 둔 컬럼과 기능상 겹치는 것도 있었는데, 일단 그대로 두고 새로운 컬럼을 넣었다.
  • 이상하게 알파벳 L이 자꾸 소문자가 아닌 대문자로 들어가는 문제가 있어 나중에 jsp의 컬럼명과 맞지 않는 등의 문제가 있었다. 어쩔 수 없이 DB의 컬럼명은 LV로 하고 mapper에서 받을 때는 depth라는 이름을 쓰기로 했다.
  • WHERE절 뒤에 START WITH~ 절을 넣어주었다.
  1. vo 변경
  • vo에 새로운 컬럼을 추가하고 getter, setter를 생성해주었다.
  1. controller 변경
  • 게시물 등록 시 새로 추가한 컬럼에 값을 넣는 로직을 추가해주었다.
// 새로운 답글 게시물 생성해서 대상ID, 답글여부, 제목, 내용 미리 설정
QnAVO reply = new QnAVO(); // 답글 게시물 생성
reply.setQtId(prevVO.getQnaId()); // 기존게시물의 id 저장
reply.setIsAnswer(1); // 답글여부 0/1
reply.setQnaSj("[RE]:" + prevVO.getQnaSj()); // 기존 게시물의 제목에 [re] 추가

String replyCn = getHtmlStrCnvr(prevVO.getQnaCn()) + "<br/><br/>------------------------------------------------------<br/><br/>"; // 기존 게시물 내용에 점선 및 줄바꿈 삽입
reply.setQnaCn(replyCn);

/* 답글 정렬용 데이터 삽입 */
reply.setParentId(prevVO.getQnaId()); 
reply.setGroupId(prevVO.getQnaId());
reply.setDepth(prevVO.getDepth()+1); // 기존 게시물 레벨+1

model.addAttribute("qnaVO", reply);
  1. jsp 변경
  • view 화면에 새로 추가한 컬럼을 input hidden으로 전달해 값이 전달될 수 있도록 했다.
<input name="parentId" type="hidden" value="<c:out value='${result.parentId}'/>"/>
<input name="groupId" type="hidden" value="<c:out value='${result.groupId}'/>"/>
<input name="depth" type="hidden" value="<c:out value='${result.depth}'/>"/>

화면에서의 최종결과

  • 원하는 대로 정렬은 되나 DB에서처럼 제목 들여쓰기는 안 됨
  • 레벨 값 가져오기에서 문제가 있는 것인지
  • 아니면 jsp단에서 공백을 제거해버리는것인지 알아봐야 할 듯 (아마 공백제거하는 로직이 있는 것 같음)
  • 그래도 답글 정렬이 되었다는 점에서 기쁘다!!

에러 해결 : XML, mapper 파일 적용 안됨

사실 sql 쿼리는 쉽게 작성했는데, 작성한 xml mapper 파일이 프로젝트에 적용되지 않아서 오후 내내 머리를 싸맸다. 분명 파일을 잘 수정해뒀는데 sql 쿼리처리 로그를 보면 수정 전 코드가 돌아가고 있었다.

수많은 블로그를 돌아다니며 여러 방법을 시도해봤지만, 알고보니 문제는 아주 쉬운 것이었다. 바로 eclipse-project-Build Automatically가 선택되어 있지 않았던 것...!
egov-mapper:소스 변경 시 적용이 잘 되지 않습니다.

도대체 이거때문에 몇 번을 clean, build하고 껐다 켰는지... 그래도 오늘 안에 알아내서 정말 다행이다.

profile
문서화를 좋아하는 개발자

0개의 댓글