设置定时任务,定时从数据库获取数据刷新redis
数据库定时任务
需要更新的数据
定时任务
public class RefreshRedisData5Minute {
public static final Logger log = LogManager.getLogger();
public static final String Job_Status_Wait = "waiting";
@Autowired
MemberProductInfoService memberProductInfoService;
@Autowired
SystemJobInfoService systemJobInfoService;
@Autowired
OrgBaseInfoMapper orgBaseInfoMapper;
@Autowired
private RedisTemplate<Object,Object> redisTemplate;
//获取类名()
private final String jobName = RefreshRedisData5Minute.class.getSimpleName();
//设置刷新时间
@Scheduled(cron="20 0/5 * * * ?") //每5分钟的20秒刷新
public void execute() {
long id = 0;
//根据类名 从数据库中查询对应的任务
SystemJobInfo systemJobInfo = systemJobInfoService.selectByJobName(jobName);
if(systemJobInfo==null){
log.warn(jobName +"job is not exist");
}else{
id = systemJobInfo.getId();
if (systemJobInfo.getStatus().equalsIgnoreCase(CommonConstant.Job_Status_Wait)) {
try{
//状态改成run,开始执行。只有处在wait被改成run状态才执行,避免自动任务频率
短导致的重复插入。
systemJobInfoService.updateStatusRun(id);
memberPackage();//会员套餐配置 5分钟一次
}catch(Exception e){
log.error(e.getMessage());
}finally{
//刷新任务执行完成 将任务改为waiting状态等待下次调用
//写在finally下保证一定会执行
systemJobInfoService.updateStatusWait(id);
}
}else{
log.warn("----- "+jobName +" is running -----");
}
}
}
定时任务具体执行方法
public void memberPackage(){
try {
int pageStart = 0;
int pageSize = 10;
//数据库默认值的orgId为null 刷新默认值所以传null
refreshRedis(null);
while (true){
//查出需要刷新的数据 避免数据过多 采用分页查询一次处理10条
List<OrgBaseInfo> list =
orgBaseInfoMapper.selectList(pageStart,pageSize);
//可加也可不加 数据为30条时 本来3次循环可以执行完 但是会执行第四次不过走到下
//面去也会跳出来
/*if (list == null || list.isEmpty()){
break;
}*/
//遍历上面的list集合 获取orgId
for (OrgBaseInfo oif:list) {
Long orgId = oif.getId();
refreshRedis(orgId);
}
//循环中查出的list数量小于pageSize值10 表示这也数据不够10条 说明已经处理完毕
if (list.size() < pageSize){
break;
}else {
//否则说明后面还有数据 继续操作后面的数据
pageStart=pageStart+pageSize;
}
}
} catch (Exception e) {
log.error(" error:"+e.getMessage());
}finally{
//log.info("-----end deal "+jobName +"-----");
}
}
刷新redis数据
public void refreshRedis(Long orgId){
//根据OrgId查询数据
List<MemberProductInfo> memberProductInfos = memberProductInfoService.getByOrgId(orgId);
//sql查询查询出来的集合对象一般用isEmpty()来判断是否为null
if (memberProductInfos == null || memberProductInfos.isEmpty()) {
//从redis中查询是否有这个key
//CarownerhomeKeyName.memberProductInfo + orgId 为redis数据库中的key
Object o =redisTemplate.opsForValue().
get(CarownerhomeKeyName.memberProductInfo + orgId);
if (o==null){
return;
}else {
//如果有这个Key但是对应的value为空就删除这个键
RedisUtil.deleteRedis(redisTemplate, CarownerhomeKeyName.memberProductInfo + orgId);
return;
}
}
//new一个和MemberProductInfo字段名一样的实体类但是继承了implements Serializable 的类
List<MemberProductInfoRedis> memberProductInfoRedisList = new ArrayList<>();
//遍历集合
for (MemberProductInfo mpi : memberProductInfos) {
MemberProductInfoRedis memberProductInfoRedis = new MemberProductInfoRedis();
//复制这个对象到memberProductInfoRedis
BeanUtils.copyProperties(mpi, memberProductInfoRedis);
//添加到集合中
memberProductInfoRedisList.add(memberProductInfoRedis);
}
if (orgId==null){
orgId=0l;
}
//刷新redis 这个方法封装了RedisTemplate<Object,Object>方法
RedisUtil.setRedis(redisTemplate,
CarownerhomeKeyName.memberProductInfo +orgId,
memberProductInfoRedisList);
}
封装RedisTemplate<Object,Object>方法
public class RedisUtil {
public static int hourtime15Day = 3600*24*15;// key的有效时间15天(60*60) 可自定义时常
public static boolean setRedis(RedisTemplate<Object,Object> redisTemplate,String key,Object o){
redisTemplate.opsForValue().set(key,o);
return true;
}
public static boolean setRedisTimeout(RedisTemplate<Object,Object> redisTemplate,String key,Object o,long timeoutSeconds){
redisTemplate.opsForValue().set(key,o);
redisTemplate.expire(key,timeoutSeconds, TimeUnit.SECONDS);//设置6秒过期
return true;
}
public static Object getValue(RedisTemplate<Object,Object> redisTemplate,String key){
return redisTemplate.opsForValue().get(key);
}
public static Object deleteRedis(RedisTemplate<Object,Object> redisTemplate,String key){
redisTemplate.delete(key);
return true;
}
}