개요
팀 프로젝트로 독서실 관리 프로그램을 만들고 있다. 좌석은 등록일과 만료일이 있고, 만료일이 지나면 좌석 상태를 '빈 좌석'으로 만들어야 한다.
Quartz 라이브러리로 스케줄러를 구성해서 처리해 보았다.
초기 설정
pom.xml에 라이브러리 추가.
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.2</version>
</dependency>
root-context.xml 네임스페이스에 task를 체크한 후
<task:annotation-driven/>
추가.
PeriodCheckTask.java
package xyz.sumtplus.task;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j;
import xyz.sumtplus.domain.LockerVO;
import xyz.sumtplus.domain.RegInfoVO;
import xyz.sumtplus.domain.SeatVO;
import xyz.sumtplus.mapper.LockerMapper;
import xyz.sumtplus.mapper.RegInfoMapper;
import xyz.sumtplus.mapper.SeatMapper;
@Log4j
@Component
@AllArgsConstructor
public class PeriodCheckTask {
private RegInfoMapper regInfoMapper;
private SeatMapper seatMapper;
private LockerMapper lockerMapper;
@Transactional
@Scheduled(cron="0 30 23 * * *")
public void checkPeriod() throws Exception {
log.warn("테스크 실행...");
log.warn("========================================");
List<RegInfoVO> regList = regInfoMapper.getExpireInfo();
if(regList.size() == 0) return;
regList.forEach(log::info);
for(RegInfoVO vo: regList) {
SeatVO seatVO = new SeatVO();
seatVO.setSno(vo.getSeatNo());
seatVO.setStatus(false);
seatVO.setUserNo(0L);
if(vo.getLockerNo() != null) {
LockerVO lockerVO = new LockerVO();
lockerVO.setLno(vo.getLockerNo());
lockerVO.setStatus(false);
lockerVO.setUserNo(0L);
lockerMapper.updateStatus(lockerVO);
log.warn(lockerVO);
}
seatMapper.updateStatus(seatVO);
log.warn(seatVO);
}
log.warn("========================================");
log.warn(regInfoMapper.deleteRegInfo());
}
}
🔶 @scheduled를 이용해서 매일 23시 30분에 실행되도록 했다.
🔶 만료된 이용 등록 정보 리스트를 불러와서 for문으로 순회했다.
🔶 만료된 이용 등록 정보에서 좌석번호(seatNo)와 사물함 번호(lockerNo)을 알아야 정보가 삭제 되면서 좌석과 사물함 이용상태도 변경할 수 있기 때문에!
🔶 항상 Null 처리도 해야 한다.
ReginfoMapper.xml 일부
<!-- 만료된 이용 등록 정보 조회 -->
<select id="getExpireInfo" resultType="xyz.sumtplus.domain.RegInfoVO">
SELECT * FROM TBL_REGINFO
<![CDATA[WHERE ENDDATE < TO_DATE(SYSDATE-1, 'YY/MM/DD')]]>
</select>
<!-- 만료일 지난 정보 삭제 -->
<delete id="deleteRegInfo">
DELETE TBL_REGINFO
WHERE REGNO IN
(SELECT REGNO
FROM
(SELECT * FROM TBL_REGINFO
<![CDATA[WHERE ENDDATE < TO_DATE(SYSDATE-1, 'YY/MM/DD')))]]>
</delete>
🔶 CDATA는 꺽쇠 때문에 필수로 써줘야 함.
🔶 등록번호를 조건으로 지워야 해서 서브쿼리를 이용했는데, 서브쿼리의 결과 행이 두 개 이상 나올 수 있다. (여러 명이 같은 날 만료 되는 경우)
🔶 단순히 WHERE 절에서 REGNO =
으로 하면 결과 행이 하나여야 하기 때문에 IN
연산자를 사용해야 한다!
'JAVA > JAVA-Project' 카테고리의 다른 글
[스프링] 독서실 관리 프로그램- 이용 기간 연장하기 21. 06. 02. 수정 (0) | 2021.05.26 |
---|---|
[스프링] 독서실 관리 프로그램 1인 1좌석 자바스크립트 21. 05. 26. (0) | 2021.05.26 |
[스프링] 게시판 글쓴이 출력 시 일부 * 처리 21. 05. 14. (0) | 2021.05.13 |
[스프링] 정보 수정 시 비밀번호 재확인, RedirectAttributes를 alert()으로 띄우기. 21. 05. 13. (0) | 2021.05.13 |
[스프링] 게시판 비밀글 설정 구현 21. 05. 05. (0) | 2021.05.05 |