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

코코·2020년 8월 18일
1

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

  • 삭제 했을 때

    • 원글만 지운다.

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

    • 답글까지 지운다.

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

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

      나는 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와 화면의 게시물 번호가 다르다는 점.
    그리고 역순 정렬을 할 수 없다는 것.

0개의 댓글