目录
一、SpringTask简介及使用方法
1.简介
2.使用方法
1)在启动类上加上@EnableScheduling注解
2)编写定时任务类Task
3.注意事项
二、实现模拟打印机定时向数据库传入数据
1.用到的DTO类
2.用到的Mapper
3.Task类
一、SpringTask简介及使用方法
1.简介
SpringTask 是 Spring 框架提供的任务调度工具,它允许按照预定的时间自动执行特定的代码逻辑。
因此我们在一个spring项目中使用SpringTask时,无须引入新的依赖。
2.使用方法
1)在启动类上加上@EnableScheduling注解
@SpringBootApplication
@EnableScheduling
public class LANApplication {public static void main(String[] args) {SpringApplication.run(LANApplication.class,args);}
}
2)编写定时任务类Task
@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类
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;
}
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
@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类
@Component
@Slf4j
public class DataInputPerDayTask {@Autowiredprivate StreamServiceImpl streamServiceImpl;@Autowiredprivate 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]; // 假设有两个scannerfor (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]; // 假设有两个zonefor (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或1jobTaskDTO.setIsOld(new Random().nextInt(2)); // 0或1jobTaskDTO.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;}
}