• Spring Task定时任务(定期删除token和无效文件)


    Spring Task定时任务

    Cron表达式

    以6-7位的一组数字,中间用空格间隔的字符串,表达一种时间

    每位的含义及取值范围:

    秒(0-59) 分(0-59) 时(0-23) 日(1-31) 月(1-12) 周(1-7或SUN-SAT) 年(四位数,可省略)

    符号的含义:

    1. *表示所有值(秒位是*,则表示每秒)
    2. ?表示未说明的值,(日和周必须有一位为?,因为不合逻辑)
    3. -表示一个指定的范围
    4. ,表示一个可能值
    5. /符号前表示开始时间,符号后表示每次递增的值
    6. L最后的,在’天’上表示这个月最后一天,用在’周’上表示’7或SUN’,在周上与数字一起,如"7L"表示这个月的最后一个周六(阿麦利卡日历,1表示周日)
    7. W只能用在’天’上, 用来描叙最接近指定天的工作日(周一到周五) ,如"15W"指"最近接这个月第15天的工作日",如果第15天是周六,那么会在第14天即周五触发
    8. # 只能在’周’上使用,用来指定这个月的第几个周几,如’6#3’表示这个月的第三个周五(6表示周五,3表示第三周).如果指定日期不存在,那么将不会触发
    9. C指和canlendar联系后计算过的值,如在’天’上标注’5C’指这个月第五天或之后包括canlendar的第一天;在’周’上标’1C’指这周日或之后包括calendar的第一天.

    当然不理解也没关系,网上一搜就有很多Cron表达式在线生成器

    实现定时任务

    背景:

    使用异步进行文件上传,将获取token文件存到数据库中,如果用户在提交表单之前反复上传文件会产生很多僵尸数据,需要使用定时任务删除僵尸token字段和上传到服务器的图片

    实现:

    1. 开启任务调度
    @EnableScheduling //开启任务调度
    @SpringBootApplication
    public class UploadApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(UploadApplication.class, args);
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    1. 编写清除僵尸token业务
    //mapper
    //获取僵尸token的id
    List<Integer> selectDeadTokens();
    //清除僵尸数据
    int deleteDeadToken(@Param("ids") List<Integer> ids);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    <delete id="deleteDeadToken">
           delete from imagetoken where id in
           <foreach collection="ids" item="e" open="(" separator="," close=")">
               #{e}
           foreach>
    delete>
    
    <select id="selectDeadTokens" resultType="java.lang.Integer">
            SELECT id FROM imagetoken t
            WHERE t.token NOT IN (select token FROM good)
    select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    //service 
    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.SERIALIZABLE)
        @Override
        public void deleteDeadToken() {
            System.out.println("---开始清除所有僵尸token---");
            List<Integer> list = imagetokenMapper.selectDeadTokens();
            System.out.println("已找到"+list.size()+"条数据");
    
            if (list.size()>0) {
                int result = imagetokenMapper.deleteDeadToken(list);
                System.out.println("本次删除"+result+"条数据");
            }
    
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. 查找数据库中存放文件地址的集合
     @Override
        public List<String> getList() {
            //条件构造器 查存放地址
            LambdaQueryWrapper<Good> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.select(Good::getSavepath);
            //this指的是当前service
            List<Good> list = this.list(queryWrapper);
    //        System.out.println("查询到的数据:");
    //        System.out.println(list);
            //获取数据库中所有图片的绝对路径List
            ArrayList<String> paths = new ArrayList<>();
            //将查到的数据中的文件地址遍历到String类型的list中
            list.stream().forEach(good -> {
                paths.add(good.getSavepath());
            });
            //System.out.println("查到的路径:"+paths);
            return  paths;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    1. 使用@Scheduled注解开启任务调度
    @Value("${image.savepath}")
        String savePath;
        /**
         * 每天晚上23点清除无效token数据并删除图片
         */
        @Scheduled(cron = "0 0 23 * * ?")
        public void delete(){
            //1.清除无效token
            imagetokenService.deleteDeadToken();
            //2.删除僵尸文件
            //2.1获取数据库中文件存储列表
            List<String> paths = goodService.getList();
            //2.2 获取图片存储地址
            File target=new File(savePath);
            //2.3遍历图片存储所在文件夹的文件
            File[] files=target.listFiles();
            for (File file : files) {
                if (file.isFile()){
                    //2.4获取存储文件的绝对地址,需要将盘符修改,
                    String absPath = file.getAbsolutePath().replaceAll("\\\\", "/");
                    //2.5将不存在的文件删除
                    if(!paths.contains(absPath)){
                         //System.out.println("要删除文件的觉得路径:"+absPath);
                         file.delete();
                     }
    
                }
            }
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
  • 相关阅读:
    杰理之修改不需要长按开机功能【篇】
    java-构造方法(超详细,奶奶都能看懂)
    计算机视觉
    消息队列 RabbitMQ入门:Linux(Docker)中安装和卸载RabbitMQ服务
    C++类构造函数和析构函数
    漏网之鱼-1、超级学习术
    【C语言刷LeetCode】1248. 统计「优美子数组」(M)
    GCN火车票识别项目 P1 火车票识别项目介绍 Pytorch LSTM/GCN
    【Python百日进阶-数据分析】Day124 - Plotly Figure参数:饼图(二)
    架构整洁之道摘录
  • 原文地址:https://blog.csdn.net/qq_45925787/article/details/126147073