springboot项目中Quartz
下面内容大家可在自己创建的 springboot项目中 玩
1 定时清理垃圾图片
定时任务组件Quartz,可以根据我们设定的周期,定时执行目标任务计划
1.1 Quartz介绍(了解)
Quartz是Job scheduling(作业调度)领域的一个开源项目,和spring完美整合。
Quartz既可以单独使用也可以跟spring框架整合使用,在实际开发中一般会使用后者。
使用Quartz可以开发一个或者多个定时任务,每个定时任务可以单独指定执行的时间,
例如每隔1小时执行一次、每个月第一天上午10点执行一次、每个月最后一天下午5点执行一次等。
官网:http://www.quartz-scheduler.org/
1.2 Quartz入门案例
基于Quartz和springboot整合的方式使用。
第一步:创建定时任务模块 : quartz-boot
导入Quartz坐标,在commons模块 导入,pom.xml文件如下
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency>
只需要在当前模块导入commons模块即可
第二步:编写quartz的任务执行对象
Springboot整合quartz 只需要通过 注解即可完成开发
- @Scheduled 任务调度执行 注解添加到目标对象的方法上即可 配置方法的执行周期- @EnableScheduling 开启任务调度 在启动类上添加
注意启动类的位置
注意:启动类要添加注解:@EnableScheduling // 开启任务调度
@Component // 定义任务实现类
public class AliyunOssScanClean {/*** 但是spring的@Scheduled只支持6位,年份是不支持的,带年份的7位格式会报错:* Cron expression must consist of 6 fields (found 7 in "1/5 * * * * ? 2018")** * @Scheduled 注解表示当前方法就是一个任务调度执行对象 * 通过cron表达式 来配置 该方法的执行周期* **/@Scheduled(cron = "*/5 * * * * ?") // 5秒 直接在方法上使用注解即可完成扫描public void run(){System.out.println("----执行扫描一次1---");}@Scheduled(cron = "*/3 * * * * ?") // 直接在方法上使用注解即可完成扫描public void run1(){System.out.println("----执行扫描一次2---");}@Scheduled(cron = "*/2 * * * * ?") // 直接在方法上使用注解即可完成扫描public void run2(){System.out.println("----执行扫描一次3---");}}
执行启动类的main 注意启动类的位置 能够扫描到AliyunOssScanClean.java 任务实现类。

@SpringBootApplication
@EnableScheduling// 开启任务调度
public class Main {public static void main(String[] args) {SpringApplication.run(Main.class,args);System.out.println("-------任务调度开启了----------");}
}
我们发现quartz 可以定时执行对应的业务! 通过我们配置文件可以修改任务执行的周期!
1.3 cron表达式学习
上面的入门案例中我们指定了一个表达式:0/3 * * * * ?
这种表达式称为cron表达式,通过cron表达式可以灵活的定义出符合要求的程序执行的时间。
本小节我们就来学习一下cron表达式的使用方法。
Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式:
(1) Seconds Minutes Hours DayofMonth Month DayofWeek Year(2)Seconds Minutes Hours DayofMonth Month DayofWeek
corn从左到右(用空格隔开):秒 分 小时 月份中的日期 月份 星期中的日期 年份

每个域都有自己允许的值和一些特殊字符构成,使用这些特殊字符可以使我们定义的表达式更加灵活。
下面是对这些特殊字符的介绍:
(1)*:表示匹配该域的任意值。假如在Minutes域使用*, 即表示每分钟都会触发事件。(2)?:只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但实际不会。因为DayofMonth和DayofWeek会相互影响。例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法: 13 13 15 20 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管星期几都会触发,实际上并不是这样。(3)-:表示范围。例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次 (4)/:表示起始时间开始触发,然后每隔固定时间触发一次。例如在Minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次. (5),:表示列出枚举值。例如:在Minutes域使用5,20,则意味着在5和20分每分钟触发一次。 (6)L:表示最后,只能出现在DayofWeek和DayofMonth域。如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。 (7)W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。例如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份 。(8)LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。 (9)#:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。
corn表达式案例:
*/5 * * * * ? 每隔5秒执行一次
0 */1 * * * ? 每隔1分钟执行一次
0 0 5-15 * * ? 每天5-15点整点触发
0 0/3 * * * ? 每三分钟触发一次
0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发
0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发
0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发0 0 12 ? * WED 表示每个星期三中午12点
0 0 17 ? * TUES,THUR,SAT 每周二、四、六下午五点
0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44触发
0 15 10 ? * MON-FRI 周一至周五的上午10:15触发"30 10 * * * ?" 每小时的10分30秒触发任务
"30 10 1 * * ?" 每天1点10分30秒触发任务
"30 10 1 20 * ?" 每月20号1点10分30秒触发任务
"30 10 1 20 10 ? *" 每年10月20号1点10分30秒触发任务
"30 10 1 20 10 ? 2011" 2011年10月20号1点10分30秒触发任务
"30 10 1 ? 10 * 2011" 2011年10月每天1点10分30秒触发任务
"30 10 1 ? 10 SUN 2011" 2011年10月每周日1点10分30秒触发任务
"15,30,45 * * * * ?" 每15秒,30秒,45秒时触发任务0 * * * * ? 每1分钟触发一次0 0 * * * ? 每天每1小时触发一次0 0 10 * * ? 每天10点触发一次0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟触发0 30 9 1 * ? 每月1号上午9点半0 15 10 15 * ? 每月15日上午10:15触发*/15 * * * * ? 每隔5秒执行一次0 */1 * * * ? 每隔1分钟执行一次0 0 5-15 * * ? 每天5-15点整点触发0 0/3 * * * ? 每三分钟触发一次0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时0 0 10,14,16 * * ? 每天上午10点,下午2点,4点0 0 12 ? * WED 表示每个星期三中午12点0 0 17 ? * TUES,THUR,SAT 每周二、四、六下午五点0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44触发0 15 10 ? * MON-FRI 周一至周五的上午10:15触发0 0 23 L * ? 每月最后一天23点执行一次0 15 10 L * ? 每月最后一日的上午10:15触发0 15 10 ? * 6L 每月的最后一个星期五上午10:15触发0 15 10 * * ? 2005 2005年的每天上午10:15触发0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最后一个星期五上午10:15触发0 15 10 ? * 6#3 每月的第三个星期五上午10:15触发
1.4 cron表达式在线生成器
前面介绍了cron表达式,但是自己编写表达式还是有一些困难的,我们可以借助一些cron表达式在线生成器来根据我们的需求生成表达式即可。
http://cron.qqe2.com/

1.5 xxl-job 分布式任务调度
XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。
Quartz的不足
问题一:调用API的的方式操作任务,不人性化;
问题二:需要持久化业务QuartzJobBean到底层数据表中,系统侵入性相当严重。
问题三:调度逻辑和QuartzJobBean耦合在同一个项目中,这将导致一个问题,在调度任务数量逐渐增多, 同时调度任务逻辑逐渐加重的情况加,此时调度系统的性能将大大受限于业务;
问题四:quartz底层以“抢占式”获取DB锁并由抢占成功节点负责运行任务,会导致节点负载悬殊非常大;而XXL-JOB通过执行器实现“协同分配式”运行任务,充分发挥集群优势,负载各节点均衡。
XXL-JOB弥补了quartz的上述不足之处。
2 Apache POI处理excel数据
POI介绍
Apache POI是用Java编写的免费开源的跨平台的Java API,Apache
POI提供API给Java程序对Microsoft
Office格式档案读和写的功能,其中使用最多的就是使用POI操作Excel文件。
POI常用对象说明:
HSSF - 提供读写Microsoft Excel XLS格式档案的功能
XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能
HWPF - 提供读写Microsoft Word DOC格式档案的功能
HSLF - 提供读写Microsoft PowerPoint格式档案的功能
HDGF - 提供读Microsoft Visio格式档案的功能
HPBF - 提供读Microsoft Publisher格式档案的功能
HSMF - 提供读Microsoft Outlook格式档案的功能
2.1 快速入门案例
目标: 从Excel文件读取数据,hello.xlsx见资料:

内容如下:

第一步:导入poi依赖
maven坐标:项目中以及无需重复导入,但是自己测试需要导入。
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.14</version>
</dependency>
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.14</version>
</dependency>
第二步:自己创建测试用例

读取excel数据
方式一
使POI可以从一个已经存在的Excel文件中读取数据
注意 读取excel文件 api编写规则顺序:工作簿-----工作区-----记录行 -----单元格
POI操作Excel表格封装了几个核心对象:
**XSSFWorkbook:工作簿
XSSFSheet:工作表
Row:行
Cell:单元格**
public class PoiTest { @Test public void demo1() throws IOException { //创建工作簿 XSSFWorkbook workbook = new XSSFWorkbook("D:\\hello.xlsx"); //获取工作表,既可以根据工作表的顺序获取,也可以根据工作表的名称获取 XSSFSheet sheet = workbook.getSheetAt(0); //遍历工作表获得行对象 for (Row row : sheet) { //遍历行对象获取单元格对象 for (Cell cell : row) { //获得单元格中的值 String value = cell.getStringCellValue(); System.out.println(value); } } workbook.close(); }
}
方式二
上面案例是通过遍历工作表获得行,遍历行获得单元格,最终获取单元格中的值。
还有一种方式就是获取工作表最后一个行号,从而根据行号获得行对象,通过行获取最后一个单元格索引,从而根据单元格索引获取每行的一个单元格对象。
代码如下:
@Test
public void demo2() throws IOException { //创建工作簿 XSSFWorkbook workbook = new XSSFWorkbook("D:\\hello.xlsx"); //获取工作表,既可以根据工作表的顺序获取,也可以根据工作表的名称获取 XSSFSheet sheet = workbook.getSheetAt(0); //获取当前工作表最后一行的行号,行号从0开始 int lastRowNum = sheet.getLastRowNum(); for(int i=0;i<=lastRowNum;i++){ //根据行号获取行对象 XSSFRow row = sheet.getRow(i); //获取当前行的最后一个单元格的索引号 short lastCellNum = row.getLastCellNum(); // row.getCell(索引) 获取指定单元格//遍历每一行上的每一个单元格 for(short j=0;j<lastCellNum;j++){ String value = row.getCell(j).getStringCellValue(); System.out.println(value); } } workbook.close();
}
第三步:poi向excel写入数据
使用POI可以在内存中创建一个Excel文件并将数据写入到这个文件,最后通过输出流将内存中的Excel文件下载到磁盘
@Test
public void demo3() throws IOException {
//在内存中创建一个Excel文件
XSSFWorkbook workbook = new XSSFWorkbook();
//创建工作表,指定工作表名称
XSSFSheet sheet = workbook.createSheet("传智播客"); //创建行,0表示第一行
XSSFRow row = sheet.createRow(0);
//创建单元格,0表示第一个单元格
row.createCell(0).setCellValue("编号");
row.createCell(1).setCellValue("名称");
row.createCell(2).setCellValue("年龄"); XSSFRow row1 = sheet.createRow(1);
row1.createCell(0).setCellValue("1");
row1.createCell(1).setCellValue("小明");
row1.createCell(2).setCellValue("10"); XSSFRow row2 = sheet.createRow(2);
row2.createCell(0).setCellValue("2");
row2.createCell(1).setCellValue("小王");
row2.createCell(2).setCellValue("20"); //通过输出流将workbook对象输出到磁盘
FileOutputStream out = new FileOutputStream("D:\\itcast.xlsx");
workbook.write(out);
out.flush();//清空缓冲区
out.close();
workbook.close(); }
经常操作excel文件,我们可以将excel的crud封装一个通用工具类
特殊的方法,可自己研究
double numberValue = row.getCell(1).getNumericCellValue(); //如果单元格没有数据,则getNumericCellValue返回0Date date= row.getCell(0).getDateCellValue(); //如果单元格没有数据,则getDateCellValue返回nullXSSFWorkbook workbook = new XSSFWorkbook(还可以是上传文件的输入流); multipartFile.getOriginalFilename();上传文件原始名multipartFile.getInputStream();上传文件输入流
相关文章:

springboot项目中Quartz
下面内容大家可在自己创建的 springboot项目中 玩1 定时清理垃圾图片定时任务组件Quartz,可以根据我们设定的周期,定时执行目标任务计划1.1 Quartz介绍(了解)Quartz是Job scheduling(作业调度)领域的一个开源项目&…...

Presto本地开发,plugin的设置
1. 新的问题 之前搭建Presto的本地开发环境时,一直使用config.properties中的plugin.bundles配置项定义需要加载的plugin模块,详细可以参考博客《win10基于IDEA,搭建Presto开发环境》presto服务启动时,指定加载哪些组件ÿ…...

2023年3月西安/杭州/深圳/东莞NPDP产品经理认证考试报名
产品经理国际资格认证NPDP是国际公认的唯一的新产品开发专业认证,集理论、方法与实践为一体的全方位的知识体系,为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。 【认证机构】 产品开发与管理协会(PDMA)成立于1979年…...

Vue3笔记01 创建项目,Composition API,新组件,其他
Vue3 创建Vue3项目 vue-cli //查看vue/cli版本,确保在4.5.0以上 vue --version //安装或升级vue/cli npm install -g vue/cli //创建项目 vue create new_project //启动 cd new_project npm run serve 也可以通过vue ui进入图形化界面进行创建 vite 新一代前端…...

pandas数据分析(二)
文章目录DataFrame数据处理与分析读取Excel文件中的数据筛选符合特定条件的数据查看数据特征和统计信息按不同标准对数据排序使用分组与聚合对员工业绩进行汇总DataFrame数据处理与分析 部分数据如下 这个数据百度可以搜到,就是下面这个 读取Excel文件中的数据 …...
Spring实现[拦截器+统一异常处理+统一数据返回]
Spring拦截器 1.实现一个普通拦截器 关键步骤 实现 HandlerInterceptor 接口重写 preHeadler 方法,在方法中编写自己的业务代码 Component public class LoginInterceptor implements HandlerInterceptor {/*** 此方法返回一个 boolean,如果为 true …...

MySQL——插入加锁/唯一索引插入死锁/批量插入效率
本篇主要介绍MySQL跟加锁相关的一些概念、MySQL执行插入Insert时的加锁过程、唯一索引下批量插入可能导致的死锁情况,以及分别从业务角度和MySQL配置角度介绍提升批量插入的效率的方法;MySQL跟加锁相关的一些概念在介绍MySQL执行插入的加锁过程之前&…...
【专项训练】数组、链表
数组array: list = []链表linked list # Definition for singly-linked list. class ListNode:def __init__(self, x):self.val = xself.next =...

基于Jeecgboot前后端分离的ERP系统开发代码生成(六)
商品信息原先生成的不符合要求,重新生成,包括一个附表商品价格信息表 一、采用TAB主题一对多的模式 因为主键,在online表单配置是灰的,所以不能进行外键管理,只能通过下面数据库进行关联录入,否则online界面…...

什么?同步代码块失效了?-- 自定义类加载器引起的问题
一、背景 最近编码过程中遇到了一个非常奇怪的问题,基于单例对象的同步代码块似乎失效了,百思不得其姐。 下面给出模拟过程和最终的结论。 二、场景描述和模拟 2.1 现象描述 Database实现单例,在 init 方法中使用同步代码块来保证 data不…...

CHAPTER 4 文件共享 - Samba
文件共享 - Samba1 Samba1.1 Samba的软件架构1.2 搭建Samba服务器1.3 samba用户管理1. 添加用户2. 修改用户密码3. 删除用户和密码4. 查看samba用户列表5. 查看samba服务器状态1.4 samba共享设置(配置文件详解)1.5 访问共享目录1. windows访问2. linux客…...

深入分析@Configuration源码
文章目录一、源码时序图1. 注册ConfigurationClassPostProcessor流程源码时序图2. 注册ConfigurationAnnotationConfig流程源码时序图3. 实例化流程源码时序图二、源码解析1. 注册ConfigurationClassPostProcessor流程源码解析(1)运行案例程序启动类Conf…...
Unity 代码优化 内存管理优化
项目遇到了卡顿的情况 仔细检查了代码没检查出有误的地方 仔细的总结了一下可以优化的东西 解决了卡顿 记录一下 1 协程 项目之前写的关于倒计时之类的东西 都是开了个协程 虽然协程是消耗很小的线程 , 可是还是有额外消耗 而且 有很多用携程来检测销毁预制体的操作 也都放到U…...

设计模式~门面(外观)模式(Facade)-08
目录 (1)优点 (2)缺点 (3)使用场景 (4)注意事项: (5)应用实例: (6)源码中的经典应用 代码 外观模式&am…...

C++面向对象编程之一:封装
C面向对象编程三大特性为:封装,继承,多态。C认为万事万物皆为对象,对象有属性和行为。比如:游戏里的地图场景可以看作是长方形对象,属性场景id,有长,有宽,可能有NPC&…...

IDEA插件系列(3):Maven Helper插件
一、引言在写Java代码的时候,我们可能会出现Jar包的冲突的问题,这时候就需要我们去解决依赖冲突了,而解决依赖冲突就需要先找到是那些依赖发生了冲突,当项目比较小的时候,还比较依靠IEDA的【Diagrams】查看依赖关系&am…...

SAP 更改物料基本计量单位
前言部分 在SAP中物料创建后,一旦发生业务,其基本计量单位便很难修改。由于单位无法满足业务要求,往往会要求新建一个物料替代旧物料。这时候除了要将旧物料上所有的未清业务删除外,还需要替换工艺与BOM中的旧物料。特别是当出现旧…...

蓝桥web基础知识学习
HTMLCSS 知识点重要指数HTML 基础标签🌟🌟🌟🌟🌟HTML5 新特性🌟🌟🌟🌟🌟HTML5 本地存储🌟🌟🌟🌟CSS 基础语法…...

Python+ChatGPT制作一个AI实用百宝箱
目录一、注册OpenAI二、搭建网站及其框架三、AI聊天机器人四、AI绘画机器人ChatGPT 最近在互联网掀起了一阵热潮,其高度智能化的功能能够给我们现实生活带来诸多的便利,可以帮助你写文章、写报告、写周报、做表格、做策划甚至还会写代码。只要与文字相关…...
Python中格式化字符串输出的4种方式
Python格式化字符串的4中方式 一、%号 二、str.format(args) 三、f-Strings 四、标准库模板 五、总结四种方式的应用场景’ 一、%号占位符 这是一种引入最早的一种,也是比较容易理解的一种方式.使用方式为: 1、格式化字符串中变化的部分使用占位符 2、…...

接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...

【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...

uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...

VisualXML全新升级 | 新增数据库编辑功能
VisualXML是一个功能强大的网络总线设计工具,专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑(如DBC、LDF、ARXML、HEX等),并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...