Quartz持久化(springboot整合mybatis版本实现调度任务持久化)--提供源码下载
1、Quartz持久化功能概述
1、实现使用quartz提供的默认11张持久化表存储quartz相关信息。
2、实现定时任务的编辑、启动、关闭、删除。
3、实现自定义持久化表存储quartz定时任务信息。
4、本案例使用springboot整合mybatis框架和MySQL数据库实现持久化
5、提供源码下载
2、认识quartz持久化
可以将调度信息存储到数据库中,进行持久化,当程序中断,再次启动的时候。任然会保留中断之前的数据,继续执行。
1、Quartz中通过JobStore来存储任务和触发器信息,Quartz默认使用RAMJobstore将任务和触发器的信息存储在内存中,但是当服务器宕机内存中的信息会丢失。
2、Quartz中通过JDBCJobStore将任务和触发器等信息保存在数据库中,实现持久化。
3、JDBCJobStoreSupport中包含两个子类:
JobStoreTX:表示自己管理事务,存储在数据库中,当程序中断,调度信息不会丢失,
支持事务,支持集群,再次启动时,会恢复因程序关闭,重启而错过的任务。
JobStoreCMT:表示使用容器管理事务
3、Quartz+MySQL持久化默认依赖的表信息
针对不同的数据库,表就放在不同的sql文件中。
如果你使用的是mysql数据库表信息就在tables_mysql.sql文件中。
重点:这些表不会自动执行,需要拷贝出来手动创建在你的数据库中。
mysql表信息如下
QRTZ _JOB_DETAILS 存储每一个已配置的Job的详细信息
QRTZ _TRIGGERS 存储已配置的Trigger的信息
QRTZ_BLOB_TRIGGERS Trigger作为Blob类型存储
QRTZ _SIMPLE_TRIGGERS 存储SimpleTrigger的信息,包括重复次数、间隔、以及已触的次数
QRTZ _CRON_TRIGGERS 存储CronTrigger,包括Cron表达式和时区信息
QRTZ _SIMPROP_TRIGGERS存储CalendarIntervalTrigger和DailyTimeIntervalTrigger两种触发器
QRTZ _CALENDARS 存储Quartz的Calendar信息
QRTZ _PAUSED_TRIGGER_GRPS 存储已暂停的Trigger组的信息
QRTZ _FIRED_TRIGGERS 存储与已触发的Trigger相关的状态信息,以及相关Job的执行信息
QRTZ _SCHEDULER_STATE 存储少量的有关Scheduler的状态信息,和别的Scheduler实例
QRTZ _LOCKS 存储程序的悲观锁的信息
创表信息如下:
#
# Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
#
# PLEASE consider using mysql with innodb tables to avoid locking issues
#
# In your Quartz properties file, you'll need to set
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#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(200) NOT NULL,JOB_GROUP VARCHAR(200) 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)
);CREATE TABLE QRTZ_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,JOB_NAME VARCHAR(200) NOT NULL,JOB_GROUP VARCHAR(200) 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(200) 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)
);CREATE TABLE QRTZ_SIMPLE_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) 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)
);CREATE TABLE QRTZ_CRON_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,CRON_EXPRESSION VARCHAR(200) 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)
);CREATE TABLE QRTZ_SIMPROP_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) 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)
);CREATE TABLE QRTZ_BLOB_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,BLOB_DATA BLOB 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)
);CREATE TABLE QRTZ_CALENDARS(SCHED_NAME VARCHAR(120) NOT NULL,CALENDAR_NAME VARCHAR(200) NOT NULL,CALENDAR BLOB NOT NULL,PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
);CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
);CREATE TABLE QRTZ_FIRED_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,ENTRY_ID VARCHAR(95) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,INSTANCE_NAME VARCHAR(200) 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(200) NULL,JOB_GROUP VARCHAR(200) NULL,IS_NONCONCURRENT VARCHAR(1) NULL,REQUESTS_RECOVERY VARCHAR(1) NULL,PRIMARY KEY (SCHED_NAME,ENTRY_ID)
);CREATE TABLE QRTZ_SCHEDULER_STATE(SCHED_NAME VARCHAR(120) NOT NULL,INSTANCE_NAME VARCHAR(200) NOT NULL,LAST_CHECKIN_TIME BIGINT(13) NOT NULL,CHECKIN_INTERVAL BIGINT(13) NOT NULL,PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
);CREATE TABLE QRTZ_LOCKS(SCHED_NAME VARCHAR(120) NOT NULL,LOCK_NAME VARCHAR(40) NOT NULL,PRIMARY KEY (SCHED_NAME,LOCK_NAME)
);commit;
4、在MySQL数据库中创建表
5、quartz默认配置文档
配置文件位置:
配置参考文档:
https://www.w3cschool.cn/quartz_doc/quartz_doc-i7oc2d9l.html
6、创建springboot工程配置quartz持久化
在正式开始之前我们需要明确一点,quartz自带的表数据的添加功能是quartz源码中自带的,我们只需要正确的配置数据源即可自动的添加数据。
6.1、创建工程引入相关包信息
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.7</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>quartzpersistencedemo3</artifactId><version>0.0.1-SNAPSHOT</version><name>quartzpersistencedemo3</name><description>quartzpersistencedemo3</description><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.49</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><image><builder>paketobuildpacks/builder-jammy-base:latest</builder></image><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build>
</project>
6.2、配置连接数据相关参数
最重要的配置就是连接数据库及job-store-type: jdbc,其他的配置如果不需要都可以不写。
最重要的配置就是连接数据库及job-store-type: jdbc,其他的配置如果不需要都可以不写。
spring:datasource:url: jdbc:mysql://localhost:3306/quartz?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=falsedriver-class-name: com.mysql.jdbc.Driverusername: rootpassword: 123456quartz:# 任务存储类型job-store-type: jdbc# 关闭时等待任务完成wait-for-jobs-to-complete-on-shutdown: false# 是否覆盖已有的任务overwrite-existing-jobs: true# 是否自动启动计划程序auto-startup: true# 延迟启动startup-delay: 0sjdbc:# 数据库架构初始化模式(never:从不进行初始化;always:每次都清空数据库进行初始化;embedded:只初始化内存数据库(默认值))# 注意:第一次启动后,需要将always改为never,否则后续每次启动都会重新初始化quartz数据库initialize-schema: never# 用于初始化数据库架构的SQL文件的路径# schema: classpath:sql/tables_mysql_innodb.sql# 相关属性配置properties:org:quartz:scheduler:# 调度器实例名称instanceName: QuartzScheduler# 分布式节点ID自动生成instanceId: AUTOjobStore:class: org.springframework.scheduling.quartz.LocalDataSourceJobStoredriverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate# 表前缀tablePrefix: QRTZ_# 是否开启集群isClustered: true# 数据源别名(自定义)dataSource: quartz# 分布式节点有效性检查时间间隔(毫秒)clusterCheckinInterval: 10000useProperties: false# 线程池配置threadPool:class: org.quartz.simpl.SimpleThreadPoolthreadCount: 10threadPriority: 5threadsInheritContextClassLoaderOfInitializingThread: true
6.3、创建quartz配置类
在配置类中配置JobDetail和trigger监听器
这个配置类只是添加任务的快捷方式,这中方式在下面的添加任务中会被替代。
@Configuration
public class QuartzJobConfig {@Beanpublic JobDetail jobDetail(){JobDetail detail= JobBuilder.newJob(MyQuartzJob.class).withIdentity("job33","group33").storeDurably()//设置Job持久化//设置job数据.usingJobData("username","xiaochun2").usingJobData("useraddr","安徽合肥2").build();return detail;}//创建触发器,触发实例@Beanpublic Trigger trigger(){//每隔5秒执行一次CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");Trigger trigger= TriggerBuilder.newTrigger().forJob(jobDetail()).withIdentity("trigger33","group33").withSchedule(cronScheduleBuilder).startNow().build();return trigger;}
}
6.4、创建job,配置任务具体内容
@Slf4j
public class MyQuartzJob extends QuartzJobBean {@Overrideprotected void executeInternal(JobExecutionContext context) throws JobExecutionException {//执行的具体内容log.info("=========quartzpersistencedemo3--quartz具体内容============");System.out.println(context.getJobInstance());System.out.println(context.getJobDetail().getJobDataMap().get("username"));}
}
6.5、启动任务并自动向数据库添加数据
从图中可以看出,任务已经顺利的启动
6.6、查看数据库数据情况
【qrtz_cron_triggers表数据】
【qrtz_job_details表数据】
【qrtz_triggers表数据】
【qrtz_scheduler_state表数据】
6.7、暂停任务
说明1:通过scheduler.pauseJob暂停任务。
说明2:scheduler.pauseJob需要的两个参数是qrtz_job_details表中的JOB_NAME和JOB_GROUP字段的值。
说明3:本案例中只涉及到任务本身的暂停,考虑到业务的并发和分布式的情况,在暂停前可以判断一下任务是否存在,如果还创建了自己的业务表,应该在任务暂停后修改自己的表状态。个人业务表的所有操作按照常规操作即可。
@Controller
public class QuartzController {@ResourceScheduler scheduler;//暂停任务@RequestMapping("/suspendJob")@ResponseBodypublic String suspendJob(){String jobName="job33";String jobGroup="group33";try{scheduler.pauseJob(JobKey.jobKey(jobName,jobGroup));return "暂停成功";}catch (Exception e){return "暂停失败";}}
}
6.8、重启任务
重点说明:这个时候重启项目,程序会自动的加载QuartzConfig并创建JobDetail和Trigger并自动的向数据库添加数据。
核心添加的qrtz_cron_triggers、qrtz_job_details、qrtz_triggers、qrtz_scheduler_state
说明1:通过scheduler.resumeJob重启任务
说明2:scheduler. resumeJob需要的两个参数是qrtz_job_details表中的JOB_NAME和JOB_GROUP字段的值。
@Controller
public class QuartzController {@ResourceScheduler scheduler;//重启任务@RequestMapping("/resumeJob")@ResponseBodypublic String resumeJob() {String jobName="job33";String jobGroup="group33";try {//恢复任务scheduler.resumeJob(JobKey.jobKey(jobName,jobGroup));return "重启成功";} catch (SchedulerException e) {return "重启失败";}}
}
6.9、删除任务
删除任务会清除数据库中的数据
@Controller
public class QuartzController {@ResourceScheduler scheduler;//删除任务@RequestMapping("/removeJob")@ResponseBodypublic String removeJob() throws SchedulerException {String jobName="job33";String jobGroup="group33";//先暂停任务scheduler.pauseJob(JobKey.jobKey(jobName,jobGroup));//获取任务触发器TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);try {//停止触发器scheduler.pauseTrigger(triggerKey);//移除触发器scheduler.unscheduleJob(triggerKey);//删除任务scheduler.deleteJob(JobKey.jobKey(jobName,jobGroup));return "删除任务成功";} catch (SchedulerException e) {return "删除任务失败";}}
}
6.10、立即启动任务
重点:只会启动一次
@Controller
public class QuartzController {@ResourceScheduler scheduler;//立即启动任务@RequestMapping("/triggerJob")@ResponseBodypublic String triggerJob() {String jobName="job33";String jobGroup="group33";try {scheduler.triggerJob(JobKey.jobKey(jobName,jobGroup));return "启动成功";} catch (SchedulerException e) {return "启动失败";}}
}
6.11、添加任务
【添加任务依赖对象】
对时区不了解,可以看这篇文章:Java中ZonedDateTime使用详解及时间转化(java中获取时区)_java zoneddatetime-CSDN博客
6.11.1、添加任务依赖对象
对时区不了解,可以看这篇文章:Java中ZonedDateTime使用详解及时间转化(java中获取时区)_java zoneddatetime-CSDN博客
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class JobInfo {private String jobName;//job名称private String jobGroup;//job所属组private String triggerName;//触发器名称private String jobDescription;//job任务描述private Map<String,Object> userData;//job携带的用户参数private String cron;//触发器规则private String timeZoneId;//当前时区
}
6.11.2、实现任务添加代码
在项目中使用到了ObjectMapper对象,将map转化成json字符串,不了解可以看文章:
Springboot中解析JSON字符串(jackson库ObjectMapper解析JSON字符串)-CSDN博客
重点:小伙伴需要注意了,创建任务的时候MyQuartzJob任务本身这个是需要提前创建的。
//添加任务
@RequestMapping(value = "/addJob",method = RequestMethod.POST)
@ResponseBody
public String addJob(@RequestBody JobInfo jobInfo) throws JsonProcessingException {System.out.println("======addJob==="+jobInfo.toString());//通过jobKey判断任务是否唯一// jobKey有jobName和jobGroup组成JobKey jobKey = JobKey.jobKey(jobInfo.getJobName(), jobInfo.getJobGroup());try {JobDetail jobDetail = scheduler.getJobDetail(jobKey);if (Objects.nonNull(jobDetail)) {scheduler.deleteJob(jobKey);}} catch (SchedulerException e) {e.printStackTrace();}//将map转化成json的工具ObjectMapper objectMapper=new ObjectMapper();//任务详情JobDetail jobDetail = JobBuilder.newJob(MyQuartzJob.class)//jobDetail描述.withDescription(jobInfo.getJobDescription()) //任务描述.usingJobData("userData",objectMapper.writeValueAsString(jobInfo.getUserData())).withIdentity(jobKey) //指定任务.build();//根据cron,TimeZone时区,指定执行计划CronScheduleBuilder builder =CronScheduleBuilder//任务表达式.cronSchedule(jobInfo.getCron()).inTimeZone(TimeZone.getTimeZone(jobInfo.getTimeZoneId()));//触发器Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobInfo.getTriggerName(), jobInfo.getJobGroup()).startNow().withSchedule(builder).build();//添加任务try {scheduler.scheduleJob(jobDetail, trigger);return "任务添加成功";} catch (SchedulerException e) {System.out.println(e.getMessage());}return "任务添加失败";
}
6.11.3、在postman中的测试
由于我们是在body中传递的数据,在addJob方法接受的参数需要使用@RequestBody注解,
如果不使用请求获取不到body的raw传递的数据。
测试参数:
{
"jobName":"jobName1",
"jobGroup":"jobGroup1",
"triggerName":"triggerName1",
"jobDescription":"三点、六点、九点发优惠卷。",
"cron":"0/5 * * * * ?",
"timeZoneId":"Asia/Shanghai",
"userData":{"name":"123"}
}
数据库参数:
结果输出:
6.12、修改任务
修改任务的本质就是添加任务,只要保证jobName,jobGroup,triggerName等关键参数不变,即可修改数据。
7、自定义任务表
Quartz总共提供了11张表来持久化分布式任务调度的相关信息,总体来说功能强大,但是比较冗余。这个时候很多人希望自己创建一张简单的表,实现任务管理也是可以的。但是这个时候对自定义表的增删改查操作都需要自己写,而无法使用默认提供了功能。
创建信息可以参照如下:
CREATE TABLE `my_job` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`jobName` varchar(50) NOT NULL COMMENT '任务名称',
`jobGroupName` varchar(50) NOT NULL COMMENT '任务组名',`jobTriggerName` varchar(50) NOT NULL COMMENT '触发器名称',
`jobCron` varchar(50) NOT NULL COMMENT '时间规则表达式',
`jobClassPath` varchar(200) NOT NULL COMMENT '类全类型',
`jobDataMap` varchar(100) DEFAULT NULL COMMENT '用户数据',
`jobStatus` int(2) NOT NULL COMMENT '任务状态',
`jobDescribe` varchar(100) DEFAULT NULL COMMENT '任务功能描述',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
值得注意的是,如果这个时候通过自定义修改了任务状态为体质状态(如停止状态为1),修改之后还需要调用scheduler.pauseJob(JobKey.jobKey(jobName,jobGroup));,任他任务也是。因为我们的停止本质只是修改数据库的值。
8、源码下载
https://download.csdn.net/download/tangshiyilang/88660404
相关文章:
Quartz持久化(springboot整合mybatis版本实现调度任务持久化)--提供源码下载
1、Quartz持久化功能概述 1、实现使用quartz提供的默认11张持久化表存储quartz相关信息。 2、实现定时任务的编辑、启动、关闭、删除。 3、实现自定义持久化表存储quartz定时任务信息。 4、本案例使用springboot整合mybatis框架和MySQL数据库实现持久化 5、提供源码下载 …...
掌握的单词个数 - 华为OD统一考试
OD统一考试 题解: Java / Python / C++ 题目描述 有一个字符串数组 words 和一个字符串 chars。假如可以用 chars 中的字母拼写出 words 中的某个"单词"(字符串),那么我们就认为你掌握了这个单词。 words 的字等仅由 a-z 英文小写宁母组成,例如“abc”。 char…...
如何使用ArcGIS Pro将Excel表转换为SHP文件
有的时候我们得到的数据是一张张的Excel表格,如果想要在ArcGIS Pro中进行分析或者制图则需要先转换为SHP格式,这里为大家介绍一下转换方法,希望能对你有所帮助。 数据来源 本教程所使用的数据是从水经微图中下载的POI数据,除了P…...
11.1Linux串口应用程序开发
UART简介 UART的全称是Universal Asynchronous Receiver and Transmitter,即异步发送和接收。 串口在嵌入式中用途非常的广泛,主要的用途有: 打印调试信息;外接各种模块:GPS、蓝牙; 串口因为结构简单、稳…...
log4j学习
依赖 <!--log4j依赖--> <dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version> </dependency><!--测试--> <dependency><groupId>org.junit.jupiter</g…...
【Vue2+3入门到实战】(4)Vue基础之指令修饰符 、v-bind对样式增强的操作、v-model应用于其他表单元素 详细示例
目录 一、今日学习目标1.指令补充 二、指令修饰符1.什么是指令修饰符?2.按键修饰符3.v-model修饰符4.事件修饰符 三、v-bind对样式控制的增强-操作class1.语法:2.对象语法3.数组语法4.代码练习 四、京东秒杀-tab栏切换导航高亮1.需求:2.准备代…...
【数据结构和算法】找到最高海拔
其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 前缀和的解题模板 2.1.1 最长递增子序列长度 2.1.2 寻找数组中第 k 大的元素 2.1.3 最长公共子序列…...
redis相关问题
1、概述: 1. 非关系型数据库 2. 是分布式缓存数据库 3. 使用 key -value结构存储 2、作用: 用作缓存降低数据库压力,提高性能;可以用作消息队列(削峰、解耦、异步调用) 3、基础语法: 基础命令…...
第41节: Vue3 watch函数
在UniApp中使用Vue3框架时,你可以使用watch函数来观察和响应Vue实例上的数据变化。以下是一个示例,演示了如何在UniApp中使用Vue3框架使用watch函数: <template> <view> <input v-model"message" type"text…...
Centos7:升级gcc、g++到版本5.2.0
背景 Centos7.9版本默认的g版本是4.8.5,在实践golang项目中,用到C14,编译时会报错:gcc: error: unrecognized command line option ‘-stdc14’ 因此,gcc需要升级到更高版本,我这里使用源码编译形式升级到g…...
Pytohn data mode plt
文章目录 文件的读写创建.csv类型的文件,并读取文件创建.xlsx文件 使用Python做图生成数据集切片取值操作修改张量中指定位置的数据 知识点torch.arange(x)torch.tensor(2)Atorch.randn(36).reshape(6,6)shapenumel()reshape(x,y,z)torch.zeros(3,3,4)torch.ones(2,…...
内网离线搭建之----kafka集群
1.系统版本 虚拟机192.168.9.184 虚拟机192.168.9.185 虚拟机192.168.9.186系统 centos7 7.6.1810 2.依赖下载 ps:置顶资源里已经下载好了,直接用!!!!!!!!…...
5.1 显示窗口的内容(一)
一,如何显示窗口的内容? 显示器用于在物理硬件(如计算机显示器或触摸屏显示器)上显示窗口的内容。 屏幕API提供的功能允许我们创建同时写入多个窗口和显示的应用程序。屏幕支持多个显示器,但创建和管理使用多个显示器…...
基于包围盒算法的三维点云数据压缩和曲面重建matlab仿真
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 包围盒构建 4.2 点云压缩 4.3 曲面重建 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ...........................................…...
关于Python里xlwings库对Excel表格的操作(十八)
这篇小笔记主要记录如何【设置单元格数据的对齐方式】。前面的小笔记已整理成目录,可点链接去目录寻找所需更方便。 【目录部分内容如下】【点击此处可进入目录】 (1)如何安装导入xlwings库; (2)如何在Wps下…...
VScode远程连接服务器,Pycharm专业版下载及远程连接(深度学习远程篇)
Visual Code、PyCharm专业版,本地和远程交互。 远程连接需要用到SSH协议的技术,常用的代码编辑器vscode 和 pycharm都有此类功能。社区版的pycharm是免费的,但是社区版不支持ssh连接服务器,只有专业版才可以,需要破解…...
Vue2和Vue3组件间通信方式汇总(3)------$bus
组件间通信方式是前端必不可少的知识点,前端开发经常会遇到组件间通信的情况,而且也是前端开发面试常问的知识点之一。接下来开始组件间通信方式第三弹------$bus,并讲讲分别在Vue2、Vue3中的表现。 Vue2Vue3组件间通信方式汇总(1)…...
PyTorch加载数据以及Tensorboard的使用
一、PyTorch加载数据初认识 Dataset:提供一种方式去获取数据及其label 如何获取每一个数据及其label 总共有多少的数据 Dataloader:为后面的网络提供不同的数据形式 数据集 在编译器中导入Dataset from torch.utils.data import Dataset 可以在jupyter中查看Dataset官方文档&…...
TensorFlow是什么
TensorFlow是什么 Tensorflow是一个Google开发的第二代机器学习系统,克服了第一代系统DistBelief仅能开发神经网络算法、难以配置、依赖Google内部硬件等局限性,应用更加广泛,并且提高了灵活性和可移植性,速度和扩展性也有了大幅…...
docker-compose 安装Sonar并集成gitlab
文章目录 1. 前置条件2. 编写docker-compose-sonar.yml文件3. 集成 gitlab4. Sonar Login with GitLab 1. 前置条件 安装docker-compose 安装docker 创建容器运行的特有网络 创建挂载目录 2. 编写docker-compose-sonar.yml文件 version: "3" services:sonar-postgre…...
支付平台在选择服务器租用时要注意什么?
如果要建设一个支付平台的话要进行服务器租用,一旦涉及到钱的方面就必须要顾虑到多方面,这样才能保证安全性,今天小编就给大家讲一讲要注意什么呢? 1、带宽:带宽是业务稳定性的直接因素,只有带宽充足,这样…...
IDEA2018升级2023,lombok插件不兼容导致get/set方法无法使用
1、问题 最近了解到一款叫CodeGeeX 的智能编程助手,想要试用一下,但是IDEA2018版本太低了,没有CodeGeeX插件,于是打算将IDEA升级到2023.2.5版本,具体升级过程略过,升级完成后,启动项目…...
企业微信服务商代开发模式获取授权企业的客户信息
服务商代开发素材: 服务商可信ip 企业微信认证 测试时不用再次创建一个企业微信,可以用当前的企业微信作为授权企业使用一、创建代开发应用模板 1,代开发模板回调URL配置 参考 注意:保存代开发应用模板时的corpId是服务商的企业…...
库存管理方法有哪些
库存管理是工作中一个离不开的话题,不管是仓管还是业务员都或多或少接触过库存管理方面的工作,例如:进货、销售、库存盘点等等这些都属于库存管理的范筹,那么库存管理方法有哪些?用哪种方法管理库存比较好,…...
数字化车间推动制造业生产创新
一、数字化车间应用场景 1:资源智能化管理 数字化车间通过搭建智能化的设备监测系统,实时采集和监控设备的运行状态和生产数据,对设备进行实时管理和维护,降低故障率和维修成本。同时,通过对生产过程中的数据采集和分…...
Linux的安装及管理程序
一、如何在linux安装卸载软件 1. 编译安装 灵活性较高 难度较大 可以安装较新的版本 2. rpm安装(redhat) linux 包安装 查软件信息:是否安装,文件列表 rpm 软件名 3. yum yum是RPM升级版本,解决rpm的弊端 安装软件 首…...
c语言-表达式求值
目录 前言一、隐式类型转换1.1 整型提升 二、算术转换三、操作符的属性四、问题表达式总结 前言 表达式求值的顺序一部分由操作符的优先级和结合性决定。 有些表达式的操作数在求值的过程中可能需要转换为其他类型 一、隐式类型转换 隐式类型转换是在编译器自动进行的类型转换…...
小型洗衣机哪个牌子质量好?口碑最好的四款小型洗衣机推荐
随着科技的快速发展,现在的人们越来越注重自己的卫生问题,不仅在吃上面会注重卫生问题,在用的上面也会更加严格要求,而衣服做为我们最贴身的东西,我们对它的要求也会更加高,所以最近这几年较火爆的无疑是内…...
springCould中的Ribbon-从小白开始【5】
目录 1.什么是Ribbo❤️❤️❤️ 2.eureka自带Ribbon ❤️❤️❤️ 3. RestTemplate❤️❤️❤️ 4.IRule❤️❤️❤️ 5.负载均衡算法❤️❤️❤️ 1.什么是Ribbo 1.Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端,负载均衡的工具。2.主要功能是提供客户端的软件…...
持续集成交付CICD:Jira 发布流水线
目录 一、实验 1.环境 2.GitLab 查看项目 3.Jira 远程触发 Jenkins 实现合并 GitLab 分支 4.K8S master节点操作 5.Jira 发布流水线 一、实验 1.环境 (1)主机 表1 主机 主机架构版本IP备注master1K8S master节点1.20.6192.168.204.180 jenkins…...
JuiceSSH结合内网穿透实现公网远程访问本地Linux虚拟机
文章目录 1. Linux安装cpolar2. 创建公网SSH连接地址3. JuiceSSH公网远程连接4. 固定连接SSH公网地址5. SSH固定地址连接测试 处于内网的虚拟机如何被外网访问呢?如何手机就能访问虚拟机呢? cpolarJuiceSSH 实现手机端远程连接Linux虚拟机(内网穿透,手机端连接Linux虚拟机) …...
使用 pytest.ini 文件控制输出 log 日志
一、前置说明 pytest.ini 文件中可以配置参数来控制 pytest 的运行行为,其存放路径要求与 conftest.py 一样。 项目根目录project_root/ ├── pytest.ini ├── tests/ │ └── test_demo.py以test开头的测试子目录project_root/ ├── tests/ │ ├── pytest.in…...
【Spring】SpringBoot 配置文件
文章目录 什么是配置文件SpringBoot配置文件配置文件快速入手配置文件的格式properties 配置文件说明properties 基本语法读取配置文件信息properties 配置格式缺点 yml 配置文件说明yml 基本语法使用 yml 连接数据库 yml 使用进阶yml 配置不同数据类型配置对象配置集合配置Map…...
Koordinator 支持 K8s 与 YARN 混部,小红书在离线混部实践分享
作者:索增增(小红书)、宋泽辉(小红书)、张佐玮(阿里云) 背景介绍 Koordinator 是一个开源项目,基于阿里巴巴在容器调度领域多年累积的经验孵化诞生,目前已经支持了 K8s…...
网游逆向分析与插件开发-游戏反调试功能的实现-项目需求与需求拆解
上一个专栏结束位置:网游逆向分析与插件开发-代码保护壳的优化-修改随机基址为固定基址-CSDN博客 上一个专栏是做了一个壳有了一定的保护,但是保护还是不够,最大的保护是根上把问题解决了,就是我不允许你对我进行调试,…...
阶段七-GitEE
Git:版本控制软件 Git的优点 1.1 协同修改 多人并行不悖的修改服务器端的同一个文件。 1.2 数据备份 不仅保存目录和文件的当前状态,还能够保存每一个提交过的历史状态。 1.3 版本管理 在保存每一个版本的文件信息的时候要做到不保存重复数据&…...
Redis小记(1)
目录 1.Redis和Mysql的区别 2.Redis常用命令 1.Redis和Mysql的区别 a:mysql和redis的存储方式不同 mysql是关系型数据库,用表来进行存储数据。 redis是通过键值对来存储数据,key使用string来标识,value可以是各种不同的数据结构。 b:mys…...
Flutter windows 环境配置
Flutter windows 环境配置 从零开始,演示flutter环境配置到启动项目,同时支持 vscode 和 android studio 目录 Flutter windows 环境配置一、环境配置1. Flutter SDK2. Android Studio3. JDK4. 拓展安装5. Visual Studio 2022二、项目创建和启动1. vsco…...
odoo17核心概念view5——ir_ui_view.py
这是view系列的第5篇文章,介绍一下view对应的后端文件ir_ui_view.py,它是base模块下的一个文件 位置:odoo\addons\base\models\ir_ui_view.py 该文件一共定义了三个模型 1.1 ir.ui.view.custom 查询数据库这个表是空的,从名字看…...
截断整型提升算数转换
文章目录 🚀前言🚀截断🚀整型提升✈️整型提升是怎样的 🚀算术转换 🚀前言 大家好啊!这里阿辉补一下前面操作符遗漏的地方——截断、整型提升和算数转换 看这一篇要先会前面阿辉讲的数据的存储否则可能看不…...
阿里云 ECS Docker、Docker Compose安装
https://help.aliyun.com/document_detail/51853.html https://docs.docker.com/compose/install/ Centos https://blog.csdn.net/Alen_xiaoxin/article/details/104850553 systemctl enable dockerdocker-compose安装 https://blog.csdn.net/qq465084127/article/details/…...
LeetCode——1276. 不浪费原料的汉堡制作方案
通过万岁!!! 题目,给你两个数tomatoSlices和cheeseSlices,然后每制作一个巨无霸汉堡则消耗4个tomatoSlices和1和cheeseSlices,每制作一个小皇堡则需要消耗2个tomatoSlices和1和cheeseSlices。问给你这两个…...
隆道吴树贵:生成式人工智能在招标采购中的应用
12月22日,由中国招标投标协会主办的招标采购数字发展大会在北京召开,北京隆道网络科技有限公司总裁吴树贵受邀出席大会,并在“招标采购数字化交易创新成果”专题会议上发言,探讨生成式人工智能如何在招标采购业务中落地应用。 本次…...
docker搭建kali及安装oneforall
前期docker的安装这里就不用多说了,直接看后面的代码 安装oneforall 1.安装git和pip3 sudo apt update sudo apt install git python3-pip -y2.克隆项目 git clone https://gitee.com/shmilylty/OneForAll.git3.安装相关依赖 cd OneForAll/ sudo apt install pyt…...
【MySQL】数据库之事务
目录 一、什么是事务 二、事务的ACID是什么? 三、有哪些典型的不一致性问题? 第一种:脏读 第二种:不可重复读 第三种:幻读 第四种:丢失更新 四、隔离级别有哪些? (1…...
AGV|RGV小车RFID传感器CNS-RFID-01/1S的RS232通讯联机方法
CNS-RFID-01/1S广泛应用于AGV小车,搬运机器人,无人叉车等领域,用于定位,驻车等应用,可通过多种通讯方式进行读写操作,支持上位机控制,支持伺服电机,PLC等控制设备联机,本…...
【Python可视化系列】一文教会你绘制美观的热力图(理论+源码)
一、问题 前文相关回顾: 【Python可视化系列】一文彻底教会你绘制美观的折线图(理论源码) 【Python可视化系列】一文教会你绘制美观的柱状图(理论源码) 【Python可视化系列】一文教会你绘制美观的直方图(理…...
百度Apollo五步入门自动驾驶:Dreamview与离线数据包分析(文末赠送apollo周边)
🎬 鸽芷咕:个人主页 🔥 个人专栏:《linux深造日志》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! ⛳️ 粉丝福利活动 ✅参与方式:通过连接报名观看课程,即可免费获取精美周边 ⛳️活动链接…...
为什么IPv6 可以作为低功耗蓝牙的物联网体系结构?
蓝牙40规范引人了低功耗蓝牙(Bluetooth Low Energy,BLE)技术。低牙是一种低能低延成本的无线通信技术。 与传统蓝牙相比,低功耗蓝牙同样使用24GHz频段,但其将信道重新划分为 40个,包含37 个数据信道和3个广播信道(传统蓝牙共使用 79 个信道)低功蓝牙的协…...
GPT每预测一个token就要调用一次模型
问题:下图调用了多少次模型? 不久以前我以为是调用一次 通过看代码是输出多少个token就调用多少次,如图所示: 我理解为分类模型 预测下一个token可以理解为分类模型,类别是vocab的所有token,每一次调用都…...