举例
@Override
public Map<String, Object> getCockpitStaffAttendanceTask() {Map<String, Object> map = new HashMap<>();int chuqin = 0; //出勤int queqin = 0; //缺勤int chidao = 0; //迟到int zaotui = 0; //早退//获取所有设备卡号 并且已经绑定了人List<CardDeviceInfo> cardDeviceInfoList = cardDeviceInfoService.list(new LambdaQueryWrapper<CardDeviceInfo>().isNotNull(CardDeviceInfo::getStaffId).eq(CardDeviceInfo::getCardStatus,0));for (CardDeviceInfo cardDeviceInfo : cardDeviceInfoList) {if (StringUtils.isNotEmpty(cardDeviceInfo.getLandId()) && StringUtils.isNotEmpty(cardDeviceInfo.getJobTimeId())){//判断当天是否有轨迹CardDeviceTrajectoryInfo cardDeviceTrajectoryInfosToDay = sanitationJobStatisticsMapper.selectToDayTrajectory(cardDeviceInfo.getImei());if (ObjectUtils.isNotEmpty(cardDeviceTrajectoryInfosToDay)){chuqin += 1;}else{queqin += 1;}//先处理作业地块和作业时间String landId = cardDeviceInfo.getLandId();String[] jobTypeSplit = cardDeviceInfo.getJobTimeId().split(",");List<String> jobTypeStartTimeList = new ArrayList<>();List<String> jobTypeEndTimeList = new ArrayList<>();List<String> geomList = sanitationJobStatisticsMapper.getGeomByLandId(Integer.parseInt(landId));for (String jobTypeId : jobTypeSplit) {// (防止多个时间段)根据作业类型编号 获取 作业时间段的开始时间以及结束时间 xml中使用forEach提取List<SanitationRoadOperationTimeInfo> list = sanitationRoadOperationTimeInfoService.lambdaQuery().eq(SanitationRoadOperationTimeInfo::getPid, Integer.parseInt(jobTypeId)).list();list.forEach(l -> {jobTypeStartTimeList.add(l.getStartTime().toString());jobTypeEndTimeList.add(l.getEndTime().toString());});}//获取最早的一条CardDeviceTrajectoryInfo chuQinTrajectory = sanitationJobStatisticsMapper.getChuQinCdTrajectory(cardDeviceInfo.getImei(), geomList);//获取最晚的一条CardDeviceTrajectoryInfo chuQinTrajectoryDesc = sanitationJobStatisticsMapper.getChuQinTrajectoryDesc(cardDeviceInfo.getImei(), geomList);//判断是否迟到if (ObjectUtils.isNotEmpty(chuQinTrajectory)){Boolean ifChiDao = sanitationJobStatisticsMapper.ifChiDao(chuQinTrajectory.getGpsTime(), jobTypeStartTimeList);if (ifChiDao){chidao += 1;}}//如果时间到达晚上17点30 则统计是否有早退人员LocalTime now = LocalTime.now(); // 获取当前时间if (now.isAfter(LocalTime.of(17, 30))) {CardDeviceTrajectoryInfo chuQinTrajectoryZt = sanitationJobStatisticsMapper.getChuQinZtTrajectory(cardDeviceInfo.getImei(), geomList);//判断是否早退if (ObjectUtils.isNotEmpty(chuQinTrajectoryZt)){Boolean ifZaoTui = sanitationJobStatisticsMapper.ifZaoTui(chuQinTrajectoryDesc.getGpsTime(), jobTypeEndTimeList);if (ifZaoTui){zaotui += 1;}}}}}map.put("chuqin",chuqin);map.put("queqin",queqin);map.put("chidao",chidao);map.put("zaotui",zaotui);return map;
}
查询消耗了38秒左右
1、定时写入数据库,从数据库中读取
如果数据量较大,字段较多,需要存储历史记录,则存入数据库会好些,存入数据库就是基本的insert语句,接口直接调用select查询出来就行了!
…
2、定时写入Redis缓存、从缓存中读取
如果数据量较少,字段较少,不需要存储历史记录的,可以直接存到Redis缓存里,接口需要的时候直接从Redis中取出即可!
package com.yutu.garden.task;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.yutu.garden.entity.CardDeviceInfo;
import com.yutu.garden.entity.CardDeviceTrajectoryInfo;
import com.yutu.garden.entity.SanitationRoadOperationTimeInfo;
import com.yutu.garden.mapper.gardens.SanitationJobStatisticsMapper;
import com.yutu.garden.service.CardDeviceInfoService;
import com.yutu.garden.service.SanitationRoadOperationTimeInfoService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;@Component
@EnableScheduling
//@ConditionalOnProperty(name = "scheduled.tasks.enabled", havingValue = "true")
@EnableAsync
public class CockpitStaffAttendanceTask {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Resourceprivate CardDeviceInfoService cardDeviceInfoService;@Resourceprivate SanitationJobStatisticsMapper sanitationJobStatisticsMapper;@Resourceprivate SanitationRoadOperationTimeInfoService sanitationRoadOperationTimeInfoService;//缓存到Redis中//每5分钟执行一次@Scheduled(cron = "0 */5 * * * ?")public void cockpitStaffAttendanceTask() {int chuqin = 0; //出勤int queqin = 0; //缺勤int chidao = 0; //迟到int zaotui = 0; //早退//获取所有设备卡号 并且已经绑定了人List<CardDeviceInfo> cardDeviceInfoList = cardDeviceInfoService.list(new LambdaQueryWrapper<CardDeviceInfo>().isNotNull(CardDeviceInfo::getStaffId).eq(CardDeviceInfo::getCardStatus,0));for (CardDeviceInfo cardDeviceInfo : cardDeviceInfoList) {if (StringUtils.isNotEmpty(cardDeviceInfo.getLandId()) && StringUtils.isNotEmpty(cardDeviceInfo.getJobTimeId())){//判断当天是否有轨迹CardDeviceTrajectoryInfo cardDeviceTrajectoryInfosToDay = sanitationJobStatisticsMapper.selectToDayTrajectory(cardDeviceInfo.getImei());if (ObjectUtils.isNotEmpty(cardDeviceTrajectoryInfosToDay)){chuqin += 1;}else{queqin += 1;}//先处理作业地块和作业时间String landId = cardDeviceInfo.getLandId();String[] jobTypeSplit = cardDeviceInfo.getJobTimeId().split(",");List<String> jobTypeStartTimeList = new ArrayList<>();List<String> jobTypeEndTimeList = new ArrayList<>();List<String> geomList = sanitationJobStatisticsMapper.getGeomByLandId(Integer.parseInt(landId));for (String jobTypeId : jobTypeSplit) {// (防止多个时间段)根据作业类型编号 获取 作业时间段的开始时间以及结束时间 xml中使用forEach提取List<SanitationRoadOperationTimeInfo> list = sanitationRoadOperationTimeInfoService.lambdaQuery().eq(SanitationRoadOperationTimeInfo::getPid, Integer.parseInt(jobTypeId)).list();list.forEach(l -> {jobTypeStartTimeList.add(l.getStartTime().toString());jobTypeEndTimeList.add(l.getEndTime().toString());});}//获取最早的一条CardDeviceTrajectoryInfo chuQinTrajectory = sanitationJobStatisticsMapper.getChuQinCdTrajectory(cardDeviceInfo.getImei(), geomList);//获取最晚的一条CardDeviceTrajectoryInfo chuQinTrajectoryDesc = sanitationJobStatisticsMapper.getChuQinTrajectoryDesc(cardDeviceInfo.getImei(), geomList);//判断是否迟到if (ObjectUtils.isNotEmpty(chuQinTrajectory)){Boolean ifChiDao = sanitationJobStatisticsMapper.ifChiDao(chuQinTrajectory.getGpsTime(), jobTypeStartTimeList);if (ifChiDao){chidao += 1;}}//如果时间到达晚上17点30 则统计是否有早退人员LocalTime now = LocalTime.now(); // 获取当前时间if (now.isAfter(LocalTime.of(17, 30))) {CardDeviceTrajectoryInfo chuQinTrajectoryZt = sanitationJobStatisticsMapper.getChuQinZtTrajectory(cardDeviceInfo.getImei(), geomList);//判断是否早退if (ObjectUtils.isNotEmpty(chuQinTrajectoryZt)){Boolean ifZaoTui = sanitationJobStatisticsMapper.ifZaoTui(chuQinTrajectoryDesc.getGpsTime(), jobTypeEndTimeList);if (ifZaoTui){zaotui += 1;}}}}}redisTemplate.opsForValue().set("schuqin", String.valueOf(chuqin));redisTemplate.opsForValue().set("squeqin", String.valueOf(queqin));redisTemplate.opsForValue().set("schidao", String.valueOf(chidao));redisTemplate.opsForValue().set("szaotui", String.valueOf(zaotui));}//打印测试@Scheduled(cron = "0 */1 * * * ?")public void getRedisValue(){String chuqin = (String) redisTemplate.opsForValue().get("chuqin");String queqin = (String) redisTemplate.opsForValue().get("queqin");String chidao = (String) redisTemplate.opsForValue().get("chidao");String zaotui = (String) redisTemplate.opsForValue().get("zaotui");System.out.println("打印出勤:"+chuqin);System.out.println("打印缺勤:"+queqin);System.out.println("打印迟到:"+chidao);System.out.println("打印早退:"+zaotui);}
}
不到1秒,从Redis中提取