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

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.dtcms.com/a/309245.html

相关文章:

  • RAGFLOW~Enable RAPTOR
  • 【云计算】云主机的亲和性策略(二):集群节点组
  • [ java 网络 ] TPC与UDP协议
  • 微波(Microwave)与毫米波(Millimeter wave)简介
  • 动态域名解析(DDNS)到底有什么用?
  • OSPF综合大实验
  • 下次接好运~
  • Oracle EBS 缺少adcfgclone.pl文件
  • 一分钟了解IO-Link 系列集线器
  • LaTeX 复杂图形绘制教程:从基础到进阶
  • Deep Height Decoupling for Precise Vision-based 3D Occupancy Prediction
  • 数据结构前篇 - 深入解析数据结构之复杂度
  • Leetcode——53. 最大子数组和
  • 如何将消息转移到新 iPhone
  • 如何将联系人从三星手机转移到 iPhone
  • MySQL 高并发下如何保证事务提交的绝对顺序?
  • 转换图(State Transition Diagram)和时序图(Sequence Diagram)画图流程图工具
  • 新手向:国内外大模型体验与评测
  • 智能图书馆管理系统开发实战系列(四):后端C++ DLL开发与模块化设计
  • 一种新的分布式ID生成方案--ULID
  • ABP VNext + Dapr Workflows:轻量级分布式工作流
  • (AC)唐克的新游戏
  • Vue3中Markdown解析与渲染的完整解决方案:从安全到性能优化
  • PostgreSQL 中删除指定数据库下的所有表结构
  • 微服务的编程测评系统9-竞赛新增-竞赛编辑
  • 如何保护 Redis 实例的安全?
  • 快速排序算法详解与洛谷例题实战
  • 【PHP 构造函数与析构函数:从基础到高级的完整指南】
  • 直播平台中的美白滤镜实现:美颜SDK的核心架构与性能优化指南
  • Qt结合ffmpeg实现图片参数调节/明亮度对比度饱和度设置/滤镜的使用