Servlet-JSP/Servlet-JSP 답변형 게시판 만들기

게시글 삭제할 때 고민했던 점

voider 2020. 9. 12. 13:35

🤯 게시글 삭제할 때 고민했던 점

  • 삭제 했을 때

    • 원글만 지운다.

      원글은 '삭제된 글입니다.'라고 띄우고 답글은 살려두는 형태

    • 답글까지 지운다.

      원글을 지우면 답글까지 지워지는 경우.

      페이스북의 경우는 답글까지 지우는 형태다. 반면 네이버는 답글은 두고 원글만 지운다.
      뭐가 더 좋은 방법일까? 상황에 따라 다를 것이다.

      나는 1번 원글만 지우는 방식을 선택했다. 댓글의 권한은 댓글을 쓴 사람에게 있다고 보기 때문이다.

어떻게 ?

처음 생각한 방식은 쿼리를 두 번 날리는 것이다.

1. 카운트 쿼리를 날린다.

2. 이 결과가 0보다 크다면, 답글이 존재하는 것이므로,
   delete가 아닌, 기존의 데이터를 없애고 '삭제된 게시물입니다.' 라는 문구로 update 한다.

3. 결과가 0이라면 답글이 없다는 것이다.
   따라서 그냥 delete 쿼리를 날린다.

이 방식의 단점은 여러 번 쿼리를 날린다는 것이다.

DB의 프로시저Procedure를 이용하면 IF-ELSE 처리를 할 수 있다는 것을 알게 되었다.
MySQL

-- 삭제한 게시물에 자식 노드(답변글)이 있는지 확인하는 프로시저
DELIMITER $$
DROP PROCEDURE IF EXISTS deletePost$$
CREATE PROCEDURE deletePost(IN bno int(10))
 BEGIN    
     SET @bno = bno;
    SET @count = (SELECT COUNT(*) FROM t_board t
                    WHERE t.p_bno = @bno);

    IF @count > 0 THEN
        UPDATE t_board t
        SET  t.title = '삭제된 게시글입니다.'
        ,t.content = ''
            ,t.id = ''
        WHERE t.bno = @bno;   

    ELSE 
    DELETE FROM t_board t
        WHERE t.bno = @bno;
    END IF;
END $$
DELIMITER 

위 쿼리는 bno를 받아서 답변글이 있는지 확인하고 있다면 업데이트를, 없다면 삭제하는 프로시저다.
이렇게 정의해두면, 나중에는

 -- CALL deletePost(bno번호);
 CALL deletePost(45);

이렇게 호출해서 사용할 수 있었다. 일종의... 메서드 같았다.


WorkBench


View

변경된 코드

화면, 컨트롤러, 서비스 계층에는 변화가 없다.
DB와 바로 연결되는 DAO에서도 변경하는 부분은 sql쿼리 한 줄 뿐이다.

DAO

테스트

    @Test
    public void deleteProcedureTest() throws ClassNotFoundException {
        Class.forName(DRIVER);
        String sql = "CALL deletePost(?)";
        log.info(sql);
        try(
            Connection conn = DriverManager.getConnection(URL,USER,PW);
            PreparedStatement pstmt = conn.prepareStatement(sql);
                ) {

            pstmt.setInt(1, 26);

            int result = pstmt.executeUpdate();

            assertTrue(result == 1);

        } catch (Exception e) {
            log.info(e.getMessage());
        }
    }

프로젝트

    public int delete(int bno) {
        String sql = "CALL deletePost(?)";
        log.info(sql);
        try(
            Connection conn = ds.getConnection();
            PreparedStatement pstmt = conn.prepareStatement(sql);
            ) {

            pstmt.setInt(1, bno);

            return pstmt.executeUpdate();

        } catch (Exception e) {
            log.info(e.getMessage());
        }
        return -1;
    }

최소한의 변화다!
만약 첫 번째 방법으로 했다면 이보다는 더 많이 변경해야 했을 것이다.

post.jsp

삭제된 게시물입니다'로 업데이트 후에, 화면처리. 화면에서 보이는 버튼 중에 '목록'만 남기고 '수정/삭제/답글'은 지워야 한다. post.jsp에 다음과 같은 부분을 추가했다.

const id = document.getElementById('id')

//id의 길이가 0이거나 ''일 때, 수정/삭제/답글 버튼을 보이지 않게 한다.
if(id.value.length==0||id==='') {
    document.getElementById('modify').style.display='none'        
    document.getElementById('rePost').style.display='none'        
    document.getElementById('remove').style.display='none'        
}

다른 버튼들이 사라진 것을 확인할 수 있다

그 외 문제점

  • '삭제된 게시물입니다'로 업데이트 후에, 화면처리. 화면에서 보이는 버튼 중에 '목록'만 남기고 '수정/삭제/답글'은 지워야 한다. 해결

    • 게시물 삭제 → 새로 고침 시 계속해서 alert창이 뜨는 이슈

    • 계층구조 때문에 DB와 화면의 게시물 번호가 다르다는 점.
      그리고 역순 정렬을 할 수 없다는 것.