고래씌

[Spring] 12-2. DB에는 존재하지 않는 파일인데 images 안에만 존재하는 파일 삭제하는 스케쥴러 본문

Server/Spring

[Spring] 12-2. DB에는 존재하지 않는 파일인데 images 안에만 존재하는 파일 삭제하는 스케쥴러

고래씌 2024. 1. 31. 13:29

1. DB에는 존재하지 않는 파일인데 images 안에만 존재하는 파일 삭제하는 스케쥴러

 * Board테이블과 BoardImg 테이블안에 있는 이미지 목록들을 모두 조회하여
 * resources/images디렉토리 안에 있는 이미지, 파일들과 대조하여
 * 하나도 일치하지 않는 이미지 파일들을 삭제
 * → DB에는 존재하지 않는 파일인데 images 안에만 존재하는 경우
 * 
 * 매달 1월 정시에 딱한번만 실행되도록 크론표현식으로 작성하시오
 * (테스트를 위해 5초간격으로 설정한후, 변경해줄것)
 
 
▶ FileDeleteScheduler.java
 
① board_img 안에 있는 모든 파일 목록 조회

package com.kh.spring.common.scheduling;

import java.io.File;
import java.util.Arrays;
import java.util.List;

import javax.servlet.ServletContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.kh.spring.board.model.service.BoardService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class FileDeleteScheduler {


	@Autowired
	private ServletContext application; // 정적파일들의 경로를 얻어오기 위해 추가
	
	@Autowired
	private BoardService boardService;
	
	@Scheduled(cron = "0/5 * * * * *")
	public void deleteFile() {
		
		// 1) board_img안에 있는 모든 파일 목록 조회
		List<String> list = boardService.selectFileList();
		log.info("list", list);
	
	}
	
}

 
 
② resources/images/board/T/에 있는 모든 이미지 파일목록 조회

package com.kh.spring.common.scheduling;

import java.io.File;
import java.util.Arrays;
import java.util.List;

import javax.servlet.ServletContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.kh.spring.board.model.service.BoardService;
import com.kh.spring.board.model.vo.BoardType;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class FileDeleteScheduler {

	@Autowired
	private ServletContext application; // 정적파일들의 경로를 얻어오기 위해 추가
	
	@Autowired
	private BoardService boardService;
	
	@Scheduled(cron = "0/5 * * * * *")
	public void deleteFile() {
		
		// 1) board_img안에 있는 모든 파일 목록 조회
		List<String> list = boardService.selectFileList();
		log.info("list", list);
		
		// 2) resources/images/board/T/에 있는 모든 이미지 파일목록 조회
		
		List<BoardType> boardTypeList = boardService.selectBoardTypeList();
		
		int count = 0;
		for(BoardType bt : boardTypeList) {
			File path = new File(application.getRealPath("resources/images/board/" + bt.getBoardCd()+"/"));
			File [] files = path.listFiles(); // 현재 디렉토리안에 존재하는 모든 파일을 배열형태로 반환
			// new File().listFiles();  --> 특정폴더 아래에 존재하는 모든 파일을 file배열 형태로 반환
			
			
			List<File> fileList = Arrays.asList(files);
			
			if(!list.isEmpty()) {
				for(File serverFile : fileList) {
					String fileName = serverFile.getName();  // 파일명 반환
					fileName = "/resources/images/board/" + bt.getBoardCd() +"/" + fileName;
					
					// List.indexOf(value) : List안에서 value와 같은 값이 있으면 해당 값의 인덱스 위치를 반환해주는 함수
					if(list.indexOf(fileName) == -1) {
						// select한 db목록에는 존재하지 않지만, 웹서버상에서는 저장된 파일인 경우
						// → 사용하고 있지 않은 파일로 간주
						log.info(fileName +"을 삭제합니다.");
						
						count++;
						serverFile.delete();
					}
				}
			}
		}
		
		log.info("총 {}개의 파일이 삭제됨", count);
		log.info("파일삭제 스케쥴러 종료");
		
		
	}
	
}

 
 
▶ boardService.java

//	board_img 안에 있는 모든 파일 목록 조회
	List<String> selectFileList();

//  boardType list 가져오기
	List<BoardType> selectBoardTypeList();

 
 
▶ boardServiceImpl.java

//	board_img 안에 있는 모든 파일 목록 조회
	@Override
	public List<String> selectFileList() {
		return  boardDao.selectFileList();
	}

//  boardType 리스트 가져오기
	@Override
	public List<BoardType> selectBoardTypeList() {
		return boardDao.selectBoardTypeList();
	}

 
 
▶ boardDao.java

	List<String> selectFileList();

 
 
▶ boardDaoImpl.java

	@Override
	public List<String> selectFileList() {
		return sqlSession.selectList("boardMapper.selectFileList");
	}

 
 
 
▶ board-mapper.xml
 

	<!-- DB에는 존재하지 않지만 images 안에만 존재하는 파일 찾기 -->
	<select id="selectFileList" resultType="string">
		SELECT
			'/resources/images/board/T/' || CHANGE_NAME
		FROM BOARD_IMG
		UNION ALL
		SELECT '/resources/images/board/' || BOARD_CD || '/' || CHANGE_NAME
		FROM BOARD
		WHERE CHANGE_NAME IS NOT NULL
	</select>

 
 
=> SQL문 결과, 다음과 같이 조회되는 것을 확인할 수 있다.
=> boardType이 C, T, I 등 모두 조회될 수 있도록 설정
 
 
▶ 결과

 
=> DB에 존재하지 않는 파일이 images 폴더안에 있던 사진들이 모두 삭제된 것을 확인할 수 있다.