通过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;
    }
}
相关推荐
Rust研习社13 小时前
组合真的优于继承吗?为什么 Rust 和 Go 都拥抱组合舍弃继承?
后端·rust·编程语言
IT_陈寒14 小时前
JavaScript的闭包把我坑惨了,说好的内存会自动回收呢?
前端·人工智能·后端
CaffeinePro14 小时前
Pydantic深度使用:数据校验、枚举、ORM映射
后端·fastapi
Chenyiax15 小时前
从 Chat 到 Responses:OpenAI API 抽象为什么变了?
后端
MariaH15 小时前
Koa和Express的区别
后端
MariaH15 小时前
Koa框架的使用
后端
luckdewei16 小时前
那个用 passlib 做认证的新同事,上线第一天就把用户密码写进了日志
后端
ping某17 小时前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
JustHappy17 小时前
我汇总了身边朋友的经历才发现,其实第一份实习是最难找的......
前端·后端·面试
uhakadotcom18 小时前
在python 的 工程化架构中 ,什么是 薄包装器层?
后端·面试·github