在許多業務系統中,需要定期清理數據庫中的歷史數據,例如每天凌晨清空臨時表或過期記錄。使用 Java 實現這類定時任務有多種方案,最常見的是結合 Spring 框架的 Quartz 調度器,或者使用 JDK 內建的 ScheduledExecutorService。
Quartz 是功能強大的開源任務調度庫,Spring 提供了便捷的整合支持。以下是基於 XML 配置的完整示例:
public class DatabaseCleanupJob extends QuartzJobBean {
private static final Logger logger = LoggerFactory.getLogger(DatabaseCleanupJob.class);
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
logger.info("定時任務啟動:開始清空數據庫...");
// 這裡編寫具體的數據庫清空邏輯,例如調用 Service 層方法
// cleanupService.truncateTempTables();
logger.info("定時任務結束:數據庫清空完成。");
}
}
<!-- 1. 定義 JobDetail -->
<bean id="databaseCleanupJob" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.example.job.DatabaseCleanupJob" />
</bean>
<!-- 2. 定義 CronTrigger,每天凌晨 2 點執行 -->
<bean id="cleanupCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="databaseCleanupJob" />
<property name="cronExpression" value="0 0 2 * * ?" />
</bean>
<!-- 3. 配置 SchedulerFactoryBean -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cleanupCronTrigger" />
</list>
</property>
</bean>
Cron 表達式說明:0 0 2 * * ? 表示每天凌晨 2 點 0 分 0 秒觸發。常用字段含義:秒 分 時 日 月 周 年(可選)。
若不想引入 Quartz 依賴,可使用 ScheduledExecutorService 實現簡單的定時邏輯:
@Component
public class SimpleScheduler {
@PostConstruct
public void init() {
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
// 計算首次執行延遲(例如下一個凌晨 2 點)
long initialDelay = computeNextRunDelay();
scheduler.scheduleAtFixedRate(() -> {
try {
cleanupDatabase();
} catch (Exception e) {
log.error("定時清空失敗", e);
}
}, initialDelay, 24 * 60 * 60, TimeUnit.SECONDS);
}
private long computeNextRunDelay() {
LocalDateTime now = LocalDateTime.now();
LocalDateTime nextRun = now.withHour(2).withMinute(0).withSecond(0).withNano(0);
if (now.isAfter(nextRun)) nextRun = nextRun.plusDays(1);
return Duration.between(now, nextRun).getSeconds();
}
private void cleanupDatabase() {
// 實際清空邏輯
}
}
對於需要高可靠性、分佈式調度、動態增減任務的場景,首選 Spring + Quartz;若只是單體應用的簡單定時清理,ScheduledExecutorService 輕量且零依賴,足以應對。根據項目規模與運維需求選型即可。