Chapter 27

ChangWoo·2023년 11월 29일
0
post-thumbnail

Part 27. 게시물의 삭제와 첨부파일

  • 게시물을 삭제할 때는 게시물이 포함된 첨부파일 역시 같이 삭제할 필요가 있다.
  • 단순히 데이터베이스 상에서 삭제만 이루어지는 게 아니라 실제 폴더 내의 파일도 같이 삭제할 필요가 있기 때문에 작업의 순서 역시 신경 써야만 한다.
  • 폴더에서의 파일 삭제는 위험한 작업이기 때문에 가능하면 뒤쪽으로 미루고 먼저 데이터베이스의 삭제 작업을 처리한 후 실제 파일을 삭제하도록 한다.

27.1 첨부파일 삭제 처리

  • 첨부파일과 관련된 SQL은 BoardAttachMapper 인터페이스와 XML 파일에 작성되어 있으므로 이를 먼저 처리한다.
< BoardAttachMapper 인터페이스 >
package org.zerock.mapper;
import java.util.List;
import org.zerock.domain.BoardAttachVO;
public interface BoardAttachMapper {
	public void insert(BoardAttachVO vo);
	public void delete(String uuid);
	public List<BoardAttachVO> findByBno(Long bno);
	public void deleteAll(Long bno);	
}
  • 실제 SQL은 XML 매퍼에 작성한다.
< BoardAttachMapper.xml >
	<delete id="deleteAll">
		delete tbl_attach where bno = #{bno}
	</delete>

27.1.1 BoardServiceImpl의 변경

  • BoardServiceImpl은 첨부파일 삭제와 실제 게시물의 삭제가 같이 처리되도록 트랜잭션 하에서 BoardAttachMapper의 deleteAll()을 호출하도록 수정한다.
< BoardServiceImpl 클래스 >
@Transactional
@Override
	public boolean remove(Long bno) {
		log.info("remove......" + bno);
		attachMapper.deleteAll(bno);
		return mapper.delete(bno) == 1;
	}

27.1.2 BoardController의 파일 삭제

  • BoardController는 데이터베이스의 삭제를 먼저 호출하고, 이후 파이를 삭제해야 한다.
  • 다만 파일을 삭제하기 위해서는 해당 게시물의 첨부파일 목록이 필요하다.
  • 문제는 첨부파일의 목록을 구한다하고 해도 이미지 파일의 경우에는 섬네일 파일이 생성되어 있으므로 이에 대한 처리가 깉이 필요하다는 점이다.
  • 따라서 작업의 순서를 정리하면 다음과 같다.
    • 해당 게시물의 첨부파일 정보를 미리 준비
    • 데이터베이스 상에서 해당 게시물과 첨부파일 데이터 삭제
    • 첨부파일 목록을 이용해 해당 폴더에서 섬네일 이미지(이미지 파일인 경우)와 일반 파일을 삭제

Criteria 수정

  • 게시물의 삭제 후에 페이지 번호나 검색 조건을 유지하면서 이동하기 위해서는 'redirect'에 필요한 파라미터들을 매번 추가해야 하는 불편함이 있다.
  • 이는 Criteria에서 처리할 수 있도록 이미 작성되어 있는지 확인한다.
< Criteria 클래스 >
	public String getListLink() {
		UriComponentsBuilder builder = UriComponentsBuilder.fromPath("")
				.queryParam("pageNum", this.pageNum)
				.queryParam("amount", this.getAmount())
				.queryParam("type", this.getType())
				.queryParam("keyword", this.getKeyword());
		return builder.toUriString();
	}
  • UriComponentesBuilder는 브라우저에서 GET 방식 등의 파라미터 전송에 사용되는 문자열(쿼리스트링(query string))을 손쉽게 처리할 수 있는 클래스다.

파일 삭제 처리

  • 파일 삭제는 BoardController에 deleteFiles()라는 메서드를 추가해 처리하도록 한다.
  • deleteFiles()는 java.nio.file 패키지의 Path를 이용해 처리한다.
< BoardController >
private void deleteFiles(List<BoardAttachVO> attachList) {
	    if(attachList == null || attachList.size() == 0) {
	      return;
	    }
	    log.info("delete attach files...................");
	    log.info(attachList);
	    attachList.forEach(attach -> {
	      try {        
	        Path file  = Paths.get("D:\\upload\\"+attach.getUploadPath()+"\\" + attach.getUuid()+"_"+ attach.getFileName());
	        Files.deleteIfExists(file);
if(Files.probeContentType(file).startsWith("image")) {
	        Path thumbNail = Paths.get("D:\\upload\\"+attach.getUploadPath()+"\\s_" + attach.getUuid()+"_"+ attach.getFileName());
	          Files.delete(thumbNail);
	        }
		   }catch(Exception e) {
	        log.error("delete file error" + e.getMessage());
	      }//end catch
	    });//end foreachd
	  }
< BoarController >
	@PostMapping("/remove")
	public String remove(@RequestParam("bno") Long bno, Criteria cri, RedirectAttributes rttr) {
		log.info("remove..." + bno);
		List<BoardAttachVO> attachList = service.getAttachList(bno);
		if (service.remove(bno)) {
			// delete Attach Files
			deleteFiles(attachList);
			rttr.addFlashAttribute("result", "success");
		}
		return "redirect:/board/list" + cri.getListLink();
	}
  • BoardController의 remove()는 삭제 젘에 먼저 해당 게시물의 첨부파일 목록을 확보한다.
  • 이후에 데이터베이스에서 게시물과 첨부파일 데이터를 삭제한다.
  • 만일 삭제에 성공했다면 실제 파일의 삭제를 시도한다.
  • 실제 첨부파일을 삭제하는 작업은 원본 파일을 삭제한 후 이미지의 경우 섬네일 파일을 추가적으로 삭제한다.
  • 삭제 화면은 별다른 처리 없이 기존 게시물의 수정/삭제 화면에서 동일하게 테스트할 수 있다.
  • 첨부파일이 존재하는 게시물을 등록하면 아래 그림과 같이 폴더 내에 파일들이 생성된다.
  • 게시물의 수정/삭제 화면에서 게시물을 삭제하면 아래와 같이 모든 내용들이 정리된다.
profile
한 걸음 한 걸음 나아가는 개발자

0개의 댓글