当前位置: 首页 > ops >正文

JavaWeb(苍穹外卖)--学习笔记16(定时任务工具Spring Task,Cron表达式)

前言

本篇文章是学习B站黑马程序员苍穹外卖的学习笔记📑。我的学习路线是Java基础语法-JavaWeb-做项目,管理端的功能学习完之后,就进入到了用户端微信小程序的开发,用户端开发的流程大致为用户登录—商品浏览(其中涉及到缓存,之前写过)—添加/查看/清空购物车—下单支付(到现在没搞懂😵‍💫)—地址簿—订单查询/超时/取消处理(巨多)…还有我没学到的🤪🤪

从订单支付这里,一直到day10,要不是很难的看不懂的,要不就是一些之前学过的,我是直接根据课程资料将代码导入,然后稍微看了看逻辑(太多太难了边学边做总结吧)。

🤔如果用户下单但一直不支付,这时就需要我们设置一定的时间,定时清理掉(既然不给钱,那我直接把你轰出去😡)。

🔍下面来看看订单状态定时处理功能的开发

1. 🙌先来了解一下Spring Task 和 Tack_cron表达式

Spring Task 是 Spring 框架提供的一个轻量级的任务调度模块,它允许你在 Spring 应用中简单地配置和执行定时任务。使用 Spring Task,你可以通过注解或者 XML 配置的方式定义定时任务,无需引入额外的库或依赖复杂的配置。(这个是ai给我的概念,我看着也有点懵🤪)

✅你可以把它理解成 手机里的“闹钟”App,只不过它是给你的 Java 程序用的。

你想让程序:每次下单后15分支不付款,就清除订单
只要告诉 Spring Task:“到时间就帮我做这件事”,它就会乖乖地按时执行。

cron表达式是一个字符串,通过cron表达式可以定义任务触发的时间。
一条 cron 任务的基本格式如下:

┌───────────── 分钟 (0 - 59)
│ ┌──────────── 小时 (0 - 23)
│ │ ┌───────────── 日期 (1 - 31)
│ │ │ ┌────────────── 月份 (1 - 12)
│ │ │ │ ┌─────────────── 星期几 (0 - 6)07 都表示周日)
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │
*   *   *   *   *   要执行的命令

常用符号说明:

在这里插入图片描述
🙌例:
0 0 * * * /backup.sh :每天零点执行 /backup.sh

*/10 * * * * /ping.sh:每 10 分钟执行一次

30 8 * * 1-5 /check.log:周一到周五早上 8:30 执行

✨注:可以直接用工具生成(更方便):奇Q在线Cron表达式生成器

2. 下面来举个例子来看看它是怎么使用的

①导入maven

启动类添加注解@EnableScheduling开启任务调度

③自定义定时任务类

package com.sky.task;
...
/*** 自定义定时任务*/@Component
@Slf4j
public class MyTask {/*** 定时任务1*/@Scheduled(cron = "0/5 * * * * ?")public void executeTask(){log.info("定时任务1开始执行:{}", new Date());}}

运行后:控制台每5秒输出一次
在这里插入图片描述

🧠最后来看看在实际项目中怎么使用:

先来看看要实现的功能:

  1. 处理超时订单:15分钟未支付,取消订单
  2. 每天凌晨1点处理一直处于派送中的订单

🔍✌️下面来看看代码:
就是结合刚刚学的内容,多加了两个注解和一个 select 语句(查询符合条件的订单再对其进行更改):

在sky-server的task包(P125创建的)下创建一个OrderTask类:

package com.sky.task;
.../*** 订单定时任务*/@Component
@Slf4j
public class OrderTask {@Autowiredprivate OrderMapper orderMapper;/*** 处理超时订单**/@Scheduled(cron = "0 * * * * ? ") // 每分钟执行一次//@Scheduled(cron = "1/5 * * * * ?")public void processTimeOutOrder(){log.info(" 定时处理超时订单:{}", LocalDateTime.now());LocalDateTime time = LocalDateTime.now().plusMinutes(-15);List<Orders> orderList = orderMapper.getByStatusAndOrderTimeLT(Orders.PENDING_PAYMENT, time);if(orderList != null && orderList.size() > 0){for (Orders orders : orderList) {orders.setStatus(Orders.CANCELLED);orders.setCancelReason("支付超时,自动取消");orders.setCancelTime(LocalDateTime.now());orderMapper.update(orders);}}}/*** 处理一直处于派送中状态的订单*/@Scheduled(cron = "0 0 1 * * ? ")//每日凌晨1点执行一次//@Scheduled(cron = "0/5 * * * * ?")public void processDeliveringOrder(){log.info("定时处理支付超时订单:{}", LocalDateTime.now());List<Orders> orderList =orderMapper.getByStatusAndOrderTimeLT(Orders.DELIVERY_IN_PROGRESS, LocalDateTime.now().plusMinutes(-60));if(orderList != null && orderList.size() > 0){for (Object orders : orderList) {Orders order = (Orders) orders;order.setStatus(Orders.COMPLETED);orderMapper.update(order);}}}}

mapper包下的OrderMapper:

 /*** 统计指定时间区间内订单数量* @param status* @param orderTime*/@Select("select * from orders where status = #{status} and order_time < #{orderTime}")List<Orders> getByStatusAndOrderTimeLT (Integer status, LocalDateTime orderTime);/*** 修改订单信息* @param orders*/void update(Orders orders);//这个语句有点长,放到其对应XML文件中了
<update id="update" parameterType="Orders">update orders<set><if test="number != null"> number=#{number}, </if><if test="status != null"> status=#{status}, </if><if test="addressBookId != null"> address_book_id=#{addressBookId}, </if><if test="orderTime != null"> order_time=#{orderTime},</if><if test="checkoutTime != null"> checkout_time=#{checkoutTime}, </if><if test="payMethod != null"> pay_method=#{payMethod}, </if><if test="payStatus != null"> pay_status=#{payStatus}, </if><if test="amount != null"> amount=#{amount}, </if><if test="remark != null"> remark=#{remark}, </if><if test="phone != null"> phone=#{phone}, </if><if test="address != null"> address=#{address}, </if><if test="userName != null"> user_name=#{userName}, </if><if test="consignee != null"> consignee=#{consignee} ,</if><if test="cancelReason != null"> cancel_reason=#{cancelReason}, </if><if test="rejectionReason != null"> rejection_reason=#{rejectionReason}, </if><if test="cancelTime != null"> cancel_time=#{cancelTime}, </if><if test="estimatedDeliveryTime != null"> estimated_delivery_time=#{estimatedDeliveryTime}, </if><if test="deliveryStatus != null"> delivery_status=#{deliveryStatus}, </if><if test="deliveryTime != null"> delivery_Time=#{deliveryTime}, </if><if test="packAmount != null"> pack_amount=#{packAmount},</if><if test="tablewareNumber != null"> tableware_number=#{tablewareNumber}, </if><if test="tablewareStatus != null"> tableware_status=#{tablewareStatus}, </if></set>where id=#{id}</update>

小白啊!!!写的不好轻喷啊🤯如果觉得写的不好,点个赞吧🤪(批评是我写作的动力)

…。。。。。。。。。。。…请添加图片描述

…。。。。。。。。。。。…

http://www.xdnf.cn/news/16763.html

相关文章:

  • 微信小程序页面间通信的实现方式
  • 《n8n基础教学》第一节:如何使用编辑器UI界面
  • 技术分享: 网关限流
  • kotlin语法和特性分析
  • 信号发生器和示波器阻抗匹配问题
  • WordPress 前端显示英文,后台显示中文的设置
  • 【苍穹外卖项目】Day05
  • 铁皮矫平机冷知识·第三弹
  • 如何保护 Redis 实例的安全?
  • uniapp基础 (一)
  • 基于倍增的LCA + kruskal重构树 + 并查集
  • 嵌入式系统教学范式演进:云端仿真平台如何重构温湿度监测实验教学
  • 前端开发(HTML,CSS,VUE,JS)从入门到精通!第二天(CSS)
  • Rust → WebAssembly 的性能剖析全指南
  • 【世纪龙科技】3D交互深度赋能-汽车整车维护仿真教学软件
  • 【世纪龙科技】汽车整车维护仿真教学软件-智构整车维护实训
  • ElasticSearch Linux 下安装及 Head 插件 | 详情
  • MySQL 和 PostgreSQL综合比对分析汇总
  • Linux(15)——进程间通信
  • 好未来披露2026财年Q1财报:净利润3128万美元,同比大增174%
  • 逻辑回归建模核心知识点梳理:原理、假设、评估指标与实战建议
  • 2025年文生图模型stable diffusion v3.5 large的全维度深度解析
  • [位运算]2411. 按位或最大的最小子数组长度
  • 赛博算命之八字测算事业运势的Java实现(四柱、五行、十神、流年、格局详细测算)
  • 【Nginx反向代理】通过Nginx反向代理将多个后端server统一到同一个端口上的方法
  • elementui中rules的validator 用法
  • Qt Quick 性能优化方法
  • Linux基础 -- 内核快速向用户态共享内核变量方案之ctl_table
  • DB-GPT 0.7.3 版本更新:支持Qwen3 Embedding和Reranker模型、支持知识库自定义检索策略等
  • python进程、线程、协程