Quartz 使用记录

官网

https://www.quartz-scheduler.org/

参考文档

什么是 Quartz?

官方描述:

Quartz is a richly featured, open source job scheduling library that can be integrated within virtually any Java application - from the smallest stand-alone application to the largest e-commerce system. Quartz can be used to create simple or complex schedules for executing tens, hundreds, or even tens-of-thousands of jobs; jobs whose tasks are defined as standard Java components that may execute virtually anything you may program them to do. The Quartz Scheduler includes many enterprise-class features, such as support for JTA transactions and clustering.

翻译:
Quartz 是一个有丰富特性,开源任务调度库,能和任意(从单个小应用到大型系统.) Java 应用集成.Quartz 用于创建简单或者混合 调度器用于执行数以千计的任务.Quartz Scheduler 包含了很多企业级特性,例如支持 JTA.

单例使用

1.下载 Jar 包

下载地址 :https://www.quartz-scheduler.org/downloads/

或者 引入pom 依赖:

<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
</dependency>
<!-- 日志简单实现 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.32</version>
<scope>compile</scope>
</dependency>

2. 将解压后lib文件夹下的 quartz-2.3.0-SNAPSHOT.jar 放于 Java 工程中

需下载 slf4j-simple.jar 包,否则使用SLF4j打印日志会报错:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

3. 配置 quartz.properties

在 classpath 添加 quartz.properties 文件,添加配置信息:

# 调度器名字
org.quartz.scheduler.instanceName = black-scheduler
# 线程池大小
org.quartz.threadPool.threadCount = 3
# 任务存储方式(RAMJobStore : 内存存储)
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

更详细配置参见 https://www.quartz-scheduler.org/documentation/quartz-2.3.0/configuration

4.编写HelloJob.java任务类

package org.black.demo.quartz;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date; import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class HelloJob implements Job{ private static final Logger LOGGER = LoggerFactory.getLogger(HelloJob.class); @Override
public void execute(JobExecutionContext context) throws JobExecutionException {
LOGGER.info("任务明细:{}", context.getJobDetail());
LOGGER.info("激活的实例ID{}",context.getFireInstanceId());
Date d =context.getFireTime();
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
LOGGER.info("调度器:{}",context.getScheduler());
LOGGER.info("调度器激活时间:{}",f.format(context.getScheduledFireTime()));
if(context.getPreviousFireTime() != null) {
LOGGER.info("上次调用时间:{}",f.format(context.getPreviousFireTime()));
}
LOGGER.info("下次调用时间:{}",f.format(context.getNextFireTime()));
LOGGER.info("触发器:{}",context.getTrigger());
LOGGER.info("触发时间:{}", f.format(d));
LOGGER.info("job 实例:{}", context.getJobInstance());
LOGGER.info("job 运行时长:{}s", context.getJobRunTime());
LOGGER.info("Job 设置的返回结果:{}",context.getResult());
LOGGER.info("MergedJobDataMap:{}", context.getMergedJobDataMap());
//
// LOGGER.info("恢复任务时对应的触发器key:{}",context.getRecoveringTriggerKey());
LOGGER.info("重复激活次数:{}",context.getRefireCount()); LocalDateTime date = LocalDateTime.now();
String curDateTime = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LOGGER.info("时间:{},当前线程:{} - 执行 HelloJob 任务",curDateTime,Thread.currentThread().getName() );
}
}

5.编写 QuartzScheduleDemo 测试类

package org.black.demo.quartz;

import java.util.Date;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; /**
* Quartz 示例
*
* @author lihw
* @date 2021-12-27 17:48:011
*/
public class QuartzScheduleDemo { private static final Logger LOGGER = LoggerFactory.getLogger(QuartzScheduleDemo.class); public static void main(String[] args) {
try {
// 从工厂类获取调度器示例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 启动调度器
scheduler.start(); // 定义一个Job 绑定到 HelloJob.class
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build(); // 定义一个触发器,每 4s 执行一次任务
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(4).repeatForever())
.build(); // 调度器调度任务
Date date = scheduler.scheduleJob(job, trigger);
LOGGER.info("Quartz 调度器启动时间:{}",date);
// 调用shutdown()方法关闭调度器,否则任务一直在运行
// scheduler.shutdown(); } catch (SchedulerException e) {
e.printStackTrace();
}
}
}

6.测试

测试结果:

[main] INFO org.quartz.impl.StdSchedulerFactory - Using default implementation for ThreadExecutor
[main] INFO org.quartz.core.SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
[main] INFO org.quartz.core.QuartzScheduler - Quartz Scheduler v.2.3.0 created.
[main] INFO org.quartz.simpl.RAMJobStore - RAMJobStore initialized.
[main] INFO org.quartz.core.QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.3.0) 'black-schedule' with instanceId 'NON_CLUSTERED'
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 3 threads.
Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered. [main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler 'black-schedule' initialized from default resource file in Quartz package: 'quartz.properties'
[main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler version: 2.3.0
[main] INFO org.quartz.core.QuartzScheduler - Scheduler black-schedule_$_NON_CLUSTERED started.
[main] INFO org.black.demo.quartz.QuartzScheduleDemo - Quartz 调度器启动时间:Tue Dec 28 11:51:03 CST 2021
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 任务明细:JobDetail 'group1.job1': jobClass: 'org.black.demo.quartz.HelloJob concurrentExectionDisallowed: false persistJobDataAfterExecution: false isDurable: false requestsRecovers: false
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 激活的实例ID1640663463495
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 调度器:org.quartz.impl.StdScheduler@4a5fecdf
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 调度器激活时间:2021-12-28 11:51:03
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 下次调用时间:2021-12-28 11:51:07
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 触发器:Trigger 'group1.trigger1': triggerClass: 'org.quartz.impl.triggers.SimpleTriggerImpl calendar: 'null' misfireInstruction: 0 nextFireTime: Tue Dec 28 11:51:07 CST 2021
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 触发时间:2021-12-28 11:51:03
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - job 实例:org.black.demo.quartz.HelloJob@4dab129f
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - job 运行时长:-1s
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - Job 设置的返回结果:null
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - MergedJobDataMap:org.quartz.JobDataMap@0
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 重复激活次数:0
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 时间:2021-12-28 11:51:03,当前线程:black-schedule_Worker-1 - 执行 HelloJob 任务
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 任务明细:JobDetail 'group1.job1': jobClass: 'org.black.demo.quartz.HelloJob concurrentExectionDisallowed: false persistJobDataAfterExecution: false isDurable: false requestsRecovers: false
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 激活的实例ID1640663463496
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 调度器:org.quartz.impl.StdScheduler@4a5fecdf
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 调度器激活时间:2021-12-28 11:51:07
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 上次调用时间:2021-12-28 11:51:03
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 下次调用时间:2021-12-28 11:51:11
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 触发器:Trigger 'group1.trigger1': triggerClass: 'org.quartz.impl.triggers.SimpleTriggerImpl calendar: 'null' misfireInstruction: 0 nextFireTime: Tue Dec 28 11:51:11 CST 2021
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 触发时间:2021-12-28 11:51:07
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - job 实例:org.black.demo.quartz.HelloJob@5a318665
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - job 运行时长:-1s
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - Job 设置的返回结果:null
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - MergedJobDataMap:org.quartz.JobDataMap@0
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 重复激活次数:0
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 时间:2021-12-28 11:51:07,当前线程:black-schedule_Worker-2 - 执行 HelloJob 任务

Cron 表达式触发器

package org.black.demo.quartz;

import java.util.Date;

import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; /**
* Quartz 示例
*
* @author lihw
* @date 2021-12-27 17:48:011
*/
public class QuartzScheduleCronTriggerDemo { private static final Logger LOGGER = LoggerFactory.getLogger(QuartzScheduleCronTriggerDemo.class); public static void main(String[] args) {
try {
// 从工厂类获取调度器示例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 启动调度器
scheduler.start(); // 定义一个Job 绑定到 HelloJob.class
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build(); // 定义一个触发器,每 10s 执行一次任务
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow()
// cron 表达式: 秒 分 时 日 月 周 年
.withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ? *"))
.build(); // 调度器调度任务
Date date = scheduler.scheduleJob(job, trigger);
LOGGER.info("Quartz 调度器启动时间:{}",date);
// 调用shutdown()方法关闭调度器,否则任务一直在运行
// scheduler.shutdown(); } catch (SchedulerException e) {
e.printStackTrace();
}
}
}

withSchedule 方法可以设置不同的触发器类型.CronScheduleBuilder 继承自 ScheduleBuilder,ScheduleBuilder 的子类一共有4个,也就是可以设置 4中类型的触发器.

Calendar 触发器

package org.black.demo.quartz;

import java.util.Date;

import org.quartz.CalendarIntervalScheduleBuilder;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; /**
* Quartz Calendar 触发器示例
*
* @author lihw
* @date 2021-12-27 17:48:011
*/
public class QuartzScheduleCalendarTriggerDemo { private static final Logger LOGGER = LoggerFactory.getLogger(QuartzScheduleCalendarTriggerDemo.class); public static void main(String[] args) {
try {
// 从工厂类获取调度器示例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 启动调度器
scheduler.start(); // 定义一个Job 绑定到 HelloJob.class
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build(); // 定义一个触发器,每 10s 执行一次任务
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow()
.withSchedule(CalendarIntervalScheduleBuilder.calendarIntervalSchedule().withIntervalInSeconds(10))
.build(); // 调度器调度任务
Date date = scheduler.scheduleJob(job, trigger);
LOGGER.info("Quartz 调度器启动时间:{}",date);
// 调用shutdown()方法关闭调度器,否则任务一直在运行
// scheduler.shutdown(); } catch (SchedulerException e) {
e.printStackTrace();
}
}
}

Daily Time 触发器

package org.black.demo.quartz;

import java.util.Date;

import org.quartz.DailyTimeIntervalScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TimeOfDay;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; /**
* Quartz daily time 触发器示例
*
* @author lihw
* @date 2021-12-27 17:48:011
*/
public class QuartzScheduleDailyTimeTriggerDemo { private static final Logger LOGGER = LoggerFactory.getLogger(QuartzScheduleDailyTimeTriggerDemo.class); public static void main(String[] args) {
try {
// 从工厂类获取调度器示例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 启动调度器
scheduler.start(); // 定义一个Job 绑定到 HelloJob.class
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build(); // 定义一个触发器,每 10s 执行一次任务,到 11点27分停止触发
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow()
.withSchedule(DailyTimeIntervalScheduleBuilder.dailyTimeIntervalSchedule().withIntervalInSeconds(10)
.endingDailyAt(TimeOfDay.hourAndMinuteOfDay(11, 27)))
.build();
// 调度器调度任务
Date date = scheduler.scheduleJob(job, trigger);
LOGGER.info("Quartz 调度器启动时间:{}", date);
// 调用shutdown()方法关闭调度器,否则任务一直在运行
// scheduler.shutdown();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}

JDBC JobStore

上边的示例都是存储在内存中,这里展示了如何存储在数据库中.

1. 执行建表语句

数据库初始化脚本在quartz-2.3.0.jar的/org/quartz/impl/jdbcjobstore/包下.我这里使用的是mysql 数据库,选择tables_mysql_innodb.sql 脚本执行.脚本内容如下:


DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS; CREATE TABLE QRTZ_JOB_DETAILS(
SCHED_NAME VARCHAR(120) NOT NULL,
JOB_NAME VARCHAR(190) NOT NULL,
JOB_GROUP VARCHAR(190) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
JOB_CLASS_NAME VARCHAR(250) NOT NULL,
IS_DURABLE VARCHAR(1) NOT NULL,
IS_NONCONCURRENT VARCHAR(1) NOT NULL,
IS_UPDATE_DATA VARCHAR(1) NOT NULL,
REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
ENGINE=InnoDB; CREATE TABLE QRTZ_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
JOB_NAME VARCHAR(190) NOT NULL,
JOB_GROUP VARCHAR(190) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
NEXT_FIRE_TIME BIGINT(13) NULL,
PREV_FIRE_TIME BIGINT(13) NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR(16) NOT NULL,
TRIGGER_TYPE VARCHAR(8) NOT NULL,
START_TIME BIGINT(13) NOT NULL,
END_TIME BIGINT(13) NULL,
CALENDAR_NAME VARCHAR(190) NULL,
MISFIRE_INSTR SMALLINT(2) NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))
ENGINE=InnoDB; CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
REPEAT_COUNT BIGINT(7) NOT NULL,
REPEAT_INTERVAL BIGINT(12) NOT NULL,
TIMES_TRIGGERED BIGINT(10) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB; CREATE TABLE QRTZ_CRON_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
CRON_EXPRESSION VARCHAR(120) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB; CREATE TABLE QRTZ_SIMPROP_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
STR_PROP_1 VARCHAR(512) NULL,
STR_PROP_2 VARCHAR(512) NULL,
STR_PROP_3 VARCHAR(512) NULL,
INT_PROP_1 INT NULL,
INT_PROP_2 INT NULL,
LONG_PROP_1 BIGINT NULL,
LONG_PROP_2 BIGINT NULL,
DEC_PROP_1 NUMERIC(13,4) NULL,
DEC_PROP_2 NUMERIC(13,4) NULL,
BOOL_PROP_1 VARCHAR(1) NULL,
BOOL_PROP_2 VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB; CREATE TABLE QRTZ_BLOB_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB; CREATE TABLE QRTZ_CALENDARS (
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR(190) NOT NULL,
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
ENGINE=InnoDB; CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
ENGINE=InnoDB; CREATE TABLE QRTZ_FIRED_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR(95) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
INSTANCE_NAME VARCHAR(190) NOT NULL,
FIRED_TIME BIGINT(13) NOT NULL,
SCHED_TIME BIGINT(13) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16) NOT NULL,
JOB_NAME VARCHAR(190) NULL,
JOB_GROUP VARCHAR(190) NULL,
IS_NONCONCURRENT VARCHAR(1) NULL,
REQUESTS_RECOVERY VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID))
ENGINE=InnoDB; CREATE TABLE QRTZ_SCHEDULER_STATE (
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR(190) NOT NULL,
LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
CHECKIN_INTERVAL BIGINT(13) NOT NULL,
PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
ENGINE=InnoDB; CREATE TABLE QRTZ_LOCKS (
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME))
ENGINE=InnoDB; CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP); CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE); CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP); commit;

2.引入 mysql 驱动包

     <!-- mysql 驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>

3.配置 quartz-jdbc.properties

## Quartz 配置信息

# 调度器名字
org.quartz.scheduler.instanceName = black-schedule
# 线程池大小
org.quartz.threadPool.threadCount = 3
# ====================================================================================== #
# 任务存储方式选择 JDBC存储(对应sql在 org.quartz.impl.jdbcjobstore.Constants 常量类中)
# JDBC 存储有两个实现 JobStoreCMT 和 JobStoreXT ,其中:
# JobStoreCMT:使用JTA容器管理事务,自己并不处理事务提交和回滚
# JobStoreTX: 通过 JDBC 自己管理事务提交和回滚,适合单体应用.
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
# 数据库驱动委派类(必须配置)
# org.quartz.impl.jdbcjobstore.StdJDBCDelegate (for fully JDBC-compliant drivers)
# org.quartz.impl.jdbcjobstore.MSSQLDelegate (for Microsoft SQL Server, and Sybase)
# org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
# org.quartz.impl.jdbcjobstore.WebLogicDelegate (for WebLogic drivers)
# org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
# org.quartz.impl.jdbcjobstore.oracle.WebLogicOracleDelegate (for Oracle drivers used within Weblogic)
# org.quartz.impl.jdbcjobstore.oracle.weblogic.WebLogicOracleDelegate (for Oracle drivers used within Weblogic)
# org.quartz.impl.jdbcjobstore.CloudscapeDelegate
# org.quartz.impl.jdbcjobstore.DB2v6Delegate
# org.quartz.impl.jdbcjobstore.DB2v7Delegate
# org.quartz.impl.jdbcjobstore.DB2v8Delegate
# org.quartz.impl.jdbcjobstore.HSQLDBDelegate
# org.quartz.impl.jdbcjobstore.PointbaseDelegate
# org.quartz.impl.jdbcjobstore.SybaseDelegate
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
# 数据源配置(必须配置) blackQuartz 是数据源名字
org.quartz.jobStore.dataSource = blackQuartz
# Quartz 表前缀
org.quartz.jobStore.tablePrefix=QRTZ_
# 指示 JobDataMaps 中的所有数据都是 String 类型,这样不用序列化存储到 BLOB 列中
org.quartz.jobStore.useProperties=false
# 多长时间认定 触发器错过了下次触发时间,默认 60000 毫秒
org.quartz.jobStore.misfireThreshold=60000
# 开启集群特性
org.quartz.jobStore.isClustered=false
# 集群检查频率间隔,默认15000毫秒
org.quartz.jobStore.clusterCheckinInterval=15000
# 一次性处理未触发的触发器最大数量,默认 20
org.quartz.jobStore.maxMisfiresToHandleAtATime=20
# 不允许 setAutoCommit(false) true-不允许,false-允许
org.quartz.jobStore.dontSetAutoCommitFalse=false
# 加锁查询 LOCKS 表的一行数据,{0}是表前缀(tablePrefix),{1}是调度器名字
org.quartz.jobStore.selectWithLockSQL="SELECT * FROM {0}LOCKS WHERE SCHED_NAME = {1} AND LOCK_NAME = ? FOR UPDATE"
# 设置事务隔离级别为串行 true-设置,false-不设置
org.quartz.jobStore.txIsolationLevelSerializable=false
# 如果 org.quartz.scheduler.batchTriggerAcquisitionMaxCount >1 那么此属性必须设置为 true
org.quartz.jobStore.acquireTriggersWithinLock=false
# 锁处理类,用于生产 Semaphore 实例在 job store data 上进行锁控制
#org.quartz.jobStore.lockHandler.class=null # 管道分隔的属性集合 在初始化阶段传给DriverDelegate使用,格式:"settingName=settingValue|otherSettingName=otherSettingValue|..."
#org.quartz.jobStore.driverDelegateInitString=
# ====================================================================================== # # ====================================================================================== #
# 数据源名字为blackQuartz的 数据源配置(数据库初始化脚本在quartz-2.3.0.jar的/org/quartz/impl/jdbcjobstore/包下)
# ====================================================================================== #
org.quartz.dataSource.blackQuartz.driver = com.mysql.cj.jdbc.Driver
org.quartz.dataSource.blackQuartz.URL = jdbc:mysql://localhost:3306/black?characterEncoding=UTF8&connectTimeout=6000&socketTimeout=6000&connectionTimeZone=Asia/Shanghai
org.quartz.dataSource.blackQuartz.user = black
org.quartz.dataSource.blackQuartz.password = Black@123
org.quartz.dataSource.blackQuartz.maxConnections = 5
org.quartz.dataSource.blackQuartz.validationQuery=select 0

4.编写测试类

package org.black.demo.quartz;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date; import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class HelloJob implements Job{ private static final Logger LOGGER = LoggerFactory.getLogger(HelloJob.class); @Override
public void execute(JobExecutionContext context) throws JobExecutionException {
LOGGER.info("任务明细:{}", context.getJobDetail());
LOGGER.info("激活的实例ID{}",context.getFireInstanceId());
Date d =context.getFireTime();
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
LOGGER.info("调度器:{}",context.getScheduler());
LOGGER.info("调度器激活时间:{}",f.format(context.getScheduledFireTime()));
if(context.getPreviousFireTime() != null) {
LOGGER.info("上次调用时间:{}",f.format(context.getPreviousFireTime()));
}
LOGGER.info("下次调用时间:{}",f.format(context.getNextFireTime()));
LOGGER.info("触发器:{}",context.getTrigger());
LOGGER.info("触发时间:{}", f.format(d));
LOGGER.info("job 实例:{}", context.getJobInstance());
LOGGER.info("job 运行时长:{}s", context.getJobRunTime());
LOGGER.info("Job 设置的返回结果:{}",context.getResult());
LOGGER.info("MergedJobDataMap:{}", context.getMergedJobDataMap());
//
// LOGGER.info("恢复任务时对应的触发器key:{}",context.getRecoveringTriggerKey());
LOGGER.info("重复激活次数:{}",context.getRefireCount()); LocalDateTime date = LocalDateTime.now();
String curDateTime = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LOGGER.info("时间:{},当前线程:{} - 执行 HelloJob 任务",curDateTime,Thread.currentThread().getName() );
}
}
package org.black.demo.quartz;

import java.util.Date;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; /**
* Quartz 示例
*
* @author lihw
* @date 2021-12-27 17:48:011
*/
public class QuartzScheduleJDBCDemo { private static final Logger LOGGER = LoggerFactory.getLogger(QuartzScheduleJDBCDemo.class); public static void main(String[] args) {
try {
// 从工厂类获取调度器示例
StdSchedulerFactory factory = new StdSchedulerFactory();
// 指定加载quartz-jdbc.properties配置
factory.initialize("quartz-jdbc.properties");
Scheduler scheduler = factory.getScheduler();
// 启动调度器
scheduler.start(); // 定义一个Job 绑定到 HelloJob.class
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build(); // 定义一个触发器,每 4s 执行一次任务
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(4).repeatForever())
.build(); // 调度器调度任务
Date date = scheduler.scheduleJob(job, trigger);
LOGGER.info("Quartz 调度器启动时间:{}",date);
// 调用shutdown()方法关闭调度器,否则任务一直在运行
// scheduler.shutdown(); } catch (SchedulerException e) {
e.printStackTrace();
}
}
}

5. 测试

控制台输出:

[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 时间:2021-12-28 11:46:05,当前线程:black-schedule_Worker-1 - 执行 HelloJob 任务
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 任务明细:JobDetail 'group1.job1': jobClass: 'org.black.demo.quartz.HelloJob concurrentExectionDisallowed: false persistJobDataAfterExecution: false isDurable: false requestsRecovers: false
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 激活的实例IDNON_CLUSTERED1640663163286
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 调度器:org.quartz.impl.StdScheduler@480a4a2d
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 调度器激活时间:2021-12-28 11:46:09
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 上次调用时间:2021-12-28 11:46:05
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 下次调用时间:2021-12-28 11:46:13
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 触发器:Trigger 'group1.trigger1': triggerClass: 'org.quartz.impl.triggers.SimpleTriggerImpl calendar: 'null' misfireInstruction: 0 nextFireTime: Tue Dec 28 11:46:13 CST 2021
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 触发时间:2021-12-28 11:46:09
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - job 实例:org.black.demo.quartz.HelloJob@f8b8a7d
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - job 运行时长:-1s
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - Job 设置的返回结果:null
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - MergedJobDataMap:org.quartz.JobDataMap@0
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 重复激活次数:0
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 时间:2021-12-28 11:46:09,当前线程:black-schedule_Worker-2 - 执行 HelloJob 任务
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 任务明细:JobDetail 'group1.job1': jobClass: 'org.black.demo.quartz.HelloJob concurrentExectionDisallowed: false persistJobDataAfterExecution: false isDurable: false requestsRecovers: false
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 激活的实例IDNON_CLUSTERED1640663163287
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 调度器:org.quartz.impl.StdScheduler@480a4a2d
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 调度器激活时间:2021-12-28 11:46:13
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 上次调用时间:2021-12-28 11:46:09
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 下次调用时间:2021-12-28 11:46:17
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 触发器:Trigger 'group1.trigger1': triggerClass: 'org.quartz.impl.triggers.SimpleTriggerImpl calendar: 'null' misfireInstruction: 0 nextFireTime: Tue Dec 28 11:46:17 CST 2021
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 触发时间:2021-12-28 11:46:13
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - job 实例:org.black.demo.quartz.HelloJob@7a800c47
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - job 运行时长:-1s
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - Job 设置的返回结果:null
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - MergedJobDataMap:org.quartz.JobDataMap@0
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 重复激活次数:0
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 时间:2021-12-28 11:46:13,当前线程:black-schedule_Worker-3 - 执行 HelloJob 任务
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 任务明细:JobDetail 'group1.job1': jobClass: 'org.black.demo.quartz.HelloJob concurrentExectionDisallowed: false persistJobDataAfterExecution: false isDurable: false requestsRecovers: false
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 激活的实例IDNON_CLUSTERED1640663163288
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 调度器:org.quartz.impl.StdScheduler@480a4a2d
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 调度器激活时间:2021-12-28 11:46:17
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 上次调用时间:2021-12-28 11:46:13
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 下次调用时间:2021-12-28 11:46:21
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 触发器:Trigger 'group1.trigger1': triggerClass: 'org.quartz.impl.triggers.SimpleTriggerImpl calendar: 'null' misfireInstruction: 0 nextFireTime: Tue Dec 28 11:46:21 CST 2021
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 触发时间:2021-12-28 11:46:17
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - job 实例:org.black.demo.quartz.HelloJob@1053e9f7
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - job 运行时长:-1s
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - Job 设置的返回结果:null
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - MergedJobDataMap:org.quartz.JobDataMap@0
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 重复激活次数:0
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 时间:2021-12-28 11:46:17,当前线程:black-schedule_Worker-1 - 执行 HelloJob 任务

执行以下sql查询 表数据:

select * from QRTZ_JOB_DETAILS;
select * from QRTZ_FIRED_TRIGGERS;
select * from QRTZ_PAUSED_TRIGGER_GRPS;
select * from QRTZ_SCHEDULER_STATE;
select * from QRTZ_LOCKS;
select * from QRTZ_SIMPLE_TRIGGERS;
select * from QRTZ_SIMPROP_TRIGGERS;
select * from QRTZ_CRON_TRIGGERS;
select * from QRTZ_BLOB_TRIGGERS;
select * from QRTZ_TRIGGERS;
select * from QRTZ_JOB_DETAILS;
select * from QRTZ_CALENDARS;

SpringBoot 集成

待续...

Quartz 使用记录的更多相关文章

  1. Quartz 学习记录1

    原因 公司有一些批量定时任务可能需要在夜间执行,用的是quartz和spring batch两个框架.quartz是个定时任务框架,spring batch是个批处理框架. 虽然我自己的小玩意儿平时不 ...

  2. quartz 实例记录

    之前介绍过了quartz的一些相关理论知识,感觉上挺简单的,实际动手操作也确实如此,去quartz的官网上把Jar包下载下来以后,会看到它的目录里有例子程序,看完第一个例子觉得还可以,但是看后面两个例 ...

  3. quartz相关记录

    1.http://www.quartz-scheduler.org/api/2.3.1-SNAPSHOT/ api地址 2.https://www.jianshu.com/p/3c3e166a7da1 ...

  4. Quartz使用记录总结

    Quartz是一个任务调度框架,最近在项目中有用到,所以做个记录总结. 一.主要元素 Scheduler:调度器,控制任务的调度,将JobDetail和Trigger注册到Scheduler加以控制. ...

  5. quartz问题记录-missed their scheduled fire-time

    这里有3个原因:1.所有的woker thread(工作线程; 辅助线程)都在运行其他的job2.scheduler(调度器)down了(关于这个down.我不太明确是shutdown了..还是挂掉了 ...

  6. Quartz学习记录

    参考资料: 官方网站 Quartz使用总结

  7. Quartz任务调度 服务日志+log4net打印日志+制作windows服务

    引言 现在许多的项目都需要定时的服务进行支撑,而我们经常用到的定时服务就是Quartz任务调度了.不过我们在使用定时Job进行获取的时候,有时候我们就需要记录一下自定义的日志,甚至我们还会对执行定时J ...

  8. Quartz SpringBoot 简单整合一下

    一次简单的代码整合记录. 数据库准备 如果是MySQL可能出现一些小问题.比如联合主键长度超限制,已经记录解决办法了. CREATE TABLE QRTZ_JOB_DETAILS ( SCHED_NA ...

  9. Quartz.net使用记录

    1.引入dll文件: nuget控制台:安装quartz:Install-Package Quartz 安装log4net:Install-Package log4net,这里使用log4net记录一 ...

随机推荐

  1. CF877F题解

    题目大意 有一个序列,每个位置上有 \(1\) 或 \(2\) 两种元素若干,每次询问一个区间,求这个区间有多少个子区间满足 \(1\) 类元素恰好比 \(2\) 类元素多 \(k\) 个. 莫队 要 ...

  2. Web网站建站过程(白嫖)——域名

    目录 1.域名注册商(选一个吧) 2.域名注册 没有域名建啥站? 1.域名注册商(选一个吧) 到时候你们就会想起: ...... 但是我们不用上面的,因为上面的太费Q,我们要用的是-- 2.域名注册 ...

  3. 040_Eureka 服务注册与发现

    目录 什么是Eureka 原理讲解 Eureka的基本架构 三大角色 盘点目前工程状况 创建Eureka服务端子模块 springcloud-eureka-7001 导入依赖 pom.xml 配置文件 ...

  4. Arch Linux 系统迁移

    镜像下载.域名解析.时间同步请点击 阿里巴巴开源镜像站 备份 Arch Linux 系统 安装 pigz 使用 pigz 多线程压缩比使用 tar 单线程压缩速度明显提升多倍 sudo pacman ...

  5. ORM,Django对数据库的连接和使用

    ORM,Django对数据库连接和使用数据 ORM(对象关系映射) 很多语言中的web框架都有这个概念 为什么要有ORM? 写程序离不开数据 新的语法,不需要我们自己写SQL语句 我们按照新的语法写代 ...

  6. javaweb项目中关于配置文件web.xml的解析

    一..启动tomcat,加载项目中的web.xml文件,创建servercontext上下文对象. 可以通过servercontext对象在应用中获取web.xml文件中的值. web应用加载的顺序与 ...

  7. python psutila模块(示例)

    # qianxiao996精心制作 #博客地址:https://blog.csdn.net/qq_36374896 import psutil import time import datetime ...

  8. 几种常用的MOS管参数、应用电路及区别:IRF540N、IRF9540N、IRF9540

    1. IRF540N,N沟道,100V,33A,44mΩ@10V 栅极(Gate-G,也叫做门极),源极(Source-S), 漏极(Drain-D) 漏源电压(Vdss) 100V 连续漏极电流(I ...

  9. 恢复训练(学不动了摸会鱼) Pt. 1

    本来下午想把pre稿子写了,咕咕咕. 群论是啥也不会了,写个polya试试(手动doge)为什么博客媛没有emoji,以后万一自己搭博客一定要加上这个小东西 polya淼题:poj1286 先复吸一下 ...

  10. 使用Redis实现关注好友的功能

    现在很多社交都有关注或者添加粉丝的功能, 类似于这样的功能我们如果采用数据库做的话只是单纯得到用户的一些粉丝或者关注列表的话是很简单也很容易实现, 但是如果我想要查出两个甚至多个用户共同关注了哪些人或 ...