通过SpringTask模拟打印机定时向数据库传入模拟数据

目录

一、SpringTask简介及使用方法

1.简介

2.使用方法

1)在启动类上加上@EnableScheduling注解

2)编写定时任务类Task

3.注意事项

二、实现模拟打印机定时向数据库传入数据

1.用到的DTO类

2.用到的Mapper

3.Task类


一、SpringTask简介及使用方法

1.简介

SpringTask 是 Spring 框架提供的任务调度工具,它允许按照预定的时间自动执行特定的代码逻辑。

因此我们在一个spring项目中使用SpringTask时,无须引入新的依赖。

2.使用方法

1)在启动类上加上@EnableScheduling注解

java 复制代码
@SpringBootApplication
@EnableScheduling
public class LANApplication {
    public static void main(String[] args) {
        SpringApplication.run(LANApplication.class,args);
    }
}

2)编写定时任务类Task

java 复制代码
@Component
@Slf4j
public class DataInputPerDayTask {

    @Scheduled(cron = "0 0 1 1/2 * ?") // 每隔一天的凌晨1点执行
    public void inputData(){

       log.info("开始向数据库加入打印机模拟数据...");

        // 生成模拟数据并调用service方法保存数据

    }

}

3.注意事项

在编写定时任务类Task时,有两个重要的地方需要注意:

1.需要在类前加上@Component注解,将这个类注入到spring容器当中交给容器管理

2.在需要定时执行的方法前加上@Scheduled注解并加上cron表达式来说明定时执行的周期

3.其中cron表达式可在在线生成网站上生成,网址如下:在线Cron表达式生成器

二、实现模拟打印机定时向数据库传入数据

1.用到的DTO类

java 复制代码
import lombok.Data;
import java.util.Date;

@Data
public class JobTaskDTO {
    private Integer id;
    private String sn;
    private String currentJobId;
    private String currentJobName;
    private Double currentJobLayerHeight;
    private Integer currentJobStartLayer;
    private Integer currentJobCurrentLayer;
    private Date currentJobStartTime;
    private Date currentJobEndTime;
    private Date currentJobEstimateTime;
    private Integer currentJobMaxLayerNo;
    private Date updTime;
    private Integer isFinish;
    private Integer isOld;
    private Double currentJobPowderUsage;
}
java 复制代码
import lombok.Data;
import java.util.Date;

@Data
public class PrinterStatisticsDTO {
    private Integer id;
    private String sn;
    private String workTimeLong;
    private String idleTimeLong;
    private Double powderUsage;
    private Double printWeight;
    private Date date;
}

2.用到的Mapper

java 复制代码
@Mapper
public interface TaskMapper {

    /**
     * 插入作业状态数据
     * @param jobTaskDTO 作业状态数据对象
     * @return 插入结果
     */
    @Insert("INSERT INTO printer_job_status (sn, current_job_id, current_job_name, current_job_layer_height, " +
            "current_job_start_layer, current_job_current_layer, current_job_start_time, current_job_end_time, " +
            "current_job_estimate_time, current_job_max_layer_no, upd_time, is_finish, is_old, " +
            "current_job_powder_usage) " +
            "VALUES (#{sn}, #{currentJobId}, #{currentJobName}, #{currentJobLayerHeight}, " +
            "#{currentJobStartLayer}, #{currentJobCurrentLayer}, #{currentJobStartTime}, #{currentJobEndTime}, " +
            "#{currentJobEstimateTime}, #{currentJobMaxLayerNo}, #{updTime}, #{isFinish}, #{isOld}, " +
            "#{currentJobPowderUsage})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insertJobStatus(JobTaskDTO jobTaskDTO);

    @Insert("INSERT INTO printer_statistics (sn, work_time_long, idle_time_long, powder_usage, print_weight, date) " +
            "VALUES (#{sn}, #{workTimeLong}, #{idleTimeLong}, #{powderUsage}, #{printWeight}, #{date})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    void insertPrinterStatistics(PrinterStatisticsDTO printerStatisticsDTO);
}

这里简单解释一下为什么要用mapper,而不是从controller和service开始往下传:

因为打印机从controller传过来的数据时字节流数据,从controller传过来在service中经过解析成对应的对象再传入数据库,如果用Task从controller中传过来,那就要模拟字节流数据和模拟http请求,特别繁琐且复杂,这里直接采用最直接的方式直接在task中封装好对象用mapper传进数据库即可。

3.Task类

java 复制代码
@Component
@Slf4j
public class DataInputPerDayTask {

    @Autowired
    private StreamServiceImpl streamServiceImpl;
    @Autowired
    private TaskMapper taskMapper;


    /**
     * 每隔一天的凌晨1点执行该方法向数据库传入打印机模拟数据(增加一条打印机)
     */
    @Scheduled(cron = "0 0 1 1/2 * ?") // 每隔一天的凌晨1点执行
//    @Scheduled(cron = "0/5 * * * * ? ") // 每隔五秒测试
    public void inputData(){
//        log.info("开始向数据库加入打印机模拟数据...");

        // 生成模拟数据并调用service方法保存数据
        //PrinterFormat printerFormat = generateMockData();
        //treamServiceImpl.savePrinterInfo(printerFormat);

    }

    /**
     * 生成打印机事件数据
     */
    @Scheduled(cron = "0 0 1 1/2 * ?") // 每隔一天的凌晨1点执行
//    @Scheduled(cron = "0/5 * * * * ? ") // 每隔五秒测试
    public void insertJobData() {
        log.info("开始向数据库加入打印机事件模拟数据...");
        JobTaskDTO jobTaskDTO = generateJobDataTask();
        taskMapper.insertJobStatus(jobTaskDTO);
    }

    @Scheduled(cron = "0 0 1 1/2 * ?") // 每隔一天的凌晨1点执行
//    @Scheduled(cron = "0/5 * * * * ? ") // 每隔五秒测试
    public void insertPrinterStatisticsData() {
        log.info("开始向数据库加入粉料模拟数据...");
        PrinterStatisticsDTO printerStatisticsDTO = generatePrinterStatisticsData();
        taskMapper.insertPrinterStatistics(printerStatisticsDTO);
    }

 //-----------------------------以下为生成模拟数据的逻辑----------------------------------------------------


    /**
     * 生成打印机模拟数据
     * @return
     */
    private PrinterFormat generateMockData() {
        PrinterFormat printerFormat = new PrinterFormat();

        // 常规属性
        General general = new General();
        general.setAirDir("Y+");
        general.setDog("SN" + new Random().nextInt(10000));
        general.setId("ID" + new Random().nextInt(10000));
        general.setManufacturer("广州晋原铭科技有限公司");
        general.setManufacturerId("JYM99999T2107GD-CN");
        general.setScannerNum(new Random().nextInt(5));
        printerFormat.setGeneral(general);

        // 振镜卡对象scanner列表
        PrinterScannerInfo[] scanners = new PrinterScannerInfo[2]; // 假设有两个scanner
        for (int i = 0; i < scanners.length; i++) {
            PrinterScannerInfo scanner = new PrinterScannerInfo();
            scanner.setColId(new Random().nextInt(10));
            scanner.setRowId(new Random().nextInt(10));
            scanner.setX0(new Random().nextDouble() * 100);
            scanner.setY0(new Random().nextDouble() * 100);
            scanners[i] = scanner;
        }
        printerFormat.setScanners(scanners);

        // 工作区属性
        Workplate workplate = new Workplate();
        workplate.setDepth((int) (new Random().nextDouble() * 100));
        workplate.setType("square");
        workplate.setWidth((int) (new Random().nextDouble() * 100));
        workplate.setZoneCols(new Random().nextInt(5));
        workplate.setZoneOverlap(new Random().nextInt(5));
        workplate.setZoneRows(new Random().nextInt(5));
        PrinterZoneInfo[] zones = new PrinterZoneInfo[2]; // 假设有两个zone
        for (int i = 0; i < zones.length; i++) {
            PrinterZoneInfo zone = new PrinterZoneInfo();
            zone.setColId(new Random().nextInt(10));
            zone.setRowId(new Random().nextInt(10));
            zone.setDepth(new Random().nextDouble() * 100);
            zone.setWidth(new Random().nextDouble() * 100);
            zone.setX0(new Random().nextDouble() * 100);
            zone.setY0(new Random().nextDouble() * 100);
            zones[i] = zone;
        }
        workplate.setZones(zones);
        printerFormat.setWorkplate(workplate);

        return printerFormat;
    }

    /**
     * 生成打印机事件数据
     * @return
     */
    private JobTaskDTO generateJobDataTask() {
        JobTaskDTO jobTaskDTO = new JobTaskDTO();
        jobTaskDTO.setSn("SN20241111");
        jobTaskDTO.setCurrentJobId("_240904_114708");
        jobTaskDTO.setCurrentJobName("auto_240904_1147");
        jobTaskDTO.setCurrentJobLayerHeight(0.029999999329447746);
        jobTaskDTO.setCurrentJobStartLayer(new Random().nextInt(769) + 1); // 假设起始层数是1到769之间的随机数
        jobTaskDTO.setCurrentJobCurrentLayer(new Random().nextInt(769) + 1); // 假设当前层数是1到769之间的随机数
        jobTaskDTO.setCurrentJobStartTime(new Date()); // 当前时间
        jobTaskDTO.setCurrentJobEndTime(addHours(jobTaskDTO.getCurrentJobStartTime(), 2)); // 两小时后的时间
        jobTaskDTO.setCurrentJobEstimateTime(addHours(jobTaskDTO.getCurrentJobStartTime(), 4)); // 四小时后的时间
        jobTaskDTO.setCurrentJobMaxLayerNo(769);
        jobTaskDTO.setUpdTime(new Date());
        jobTaskDTO.setIsFinish(new Random().nextInt(2)); // 0或1
        jobTaskDTO.setIsOld(new Random().nextInt(2)); // 0或1
        jobTaskDTO.setCurrentJobPowderUsage(Math.random() * 100); // 假设粉末使用量是0到100之间的随机数

        return jobTaskDTO;
    }

    /**
     * 生成打印机事件模拟数据所用的方法,用于给时间往后推x小时
     * @param date
     * @param hours
     * @return
     */
    private Date addHours(Date date, int hours) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.HOUR_OF_DAY, hours);
        return cal.getTime();
    }



    private PrinterStatisticsDTO generatePrinterStatisticsData() {
        PrinterStatisticsDTO dto = new PrinterStatisticsDTO();
        dto.setSn("SN20241111");
        Random random = new Random();
        dto.setWorkTimeLong(String.valueOf(random.nextInt(900) + 100));
        dto.setIdleTimeLong(String.valueOf(random.nextInt(900) + 100));
        DecimalFormat decimalFormat = new DecimalFormat("0.00000000");
        dto.setPowderUsage(Double.valueOf(decimalFormat.format(Math.random())));
        dto.setPrintWeight(0.0);
        dto.setDate(new Date());
        return dto;
    }
}
相关推荐
yangmc0422 分钟前
判断子序列
开发语言·数据结构·c++·算法·矩阵·图论
李小白6644 分钟前
二叉树的练习题(中)
java·数据结构·算法
骑鱼过海的猫1231 小时前
【redis】redis
java·数据库·redis
漫天转悠1 小时前
Java21和Java8性能优化详细对比
java
昇腾CANN1 小时前
Ascend C算子性能优化实用技巧05——API使用优化
c语言·开发语言·性能优化
逐星ing1 小时前
[AIGC]使用阿里云Paraformer语音识别录音识别 API 进行音频处理 —— 完整流程及代码示例
人工智能·spring·阿里云·aigc·语音识别
y25081 小时前
《抽象类和接口》
java·开发语言
脸红ฅฅ*的思春期1 小时前
Java安全—log4j日志&FastJson序列化&JNDI注入
java·安全·log4j·fastjson·jndi注入
沐泽Mu1 小时前
嵌入式学习-C嘎嘎-Day03
c语言·开发语言·c++·学习
yyycqupt1 小时前
多路转接之poll
服务器·c++·后端·网络协议