HRedisService.java 5.53 KB
package com.bsth.redis;

import com.bsth.Application;
import com.bsth.entity.HInfo;
import com.bsth.redis.util.RedisUtils;
import com.bsth.repository.HInfoRepository;
import com.bsth.util.ConfigUtil;
import com.bsth.util.ConvertUtil;
import com.google.common.collect.ArrayListMultimap;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 油量数据Redis缓存
 * Created by panzhao on 2017/3/19.
 */
@Service
@Order(3)
public class HRedisService implements CommandLineRunner {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    HInfoRepository hInfoRepository;

    @Autowired
    RedisUtils redisUtils;

    static Logger logger = LoggerFactory.getLogger(HRedisService.class);

    private final static String REDIS_KEY_PREFIX = "H:";

    /**
     * 将油量数据写入redis
     *
     * @param list
     */
    public void wirte(List<HInfo> list) {
        ArrayListMultimap<String, HInfo> multimap;
        try {
            if (list.size() == 0)
                return;
            //按日期和线路分组数据
            Class clazz = HInfo.class;
            multimap = new ConvertUtil().groupMultiList(list, ":", clazz.getDeclaredField("nbbm"), clazz.getDeclaredField("rq"));

            //写入redis
            Iterator<String> iterator = multimap.keySet().iterator();
            String key;
            while (iterator.hasNext()) {
                key = iterator.next();
                mergeData(key, multimap.get(key));
            }
        } catch (Exception e) {
            logger.error("", e);
        }
    }

    /**
     * 根据车辆和日期获取油耗数据,以 车辆_驾驶员 为key
     *
     * @param nbbmArray
     * @param rq
     * @return
     */
    public ArrayListMultimap findByNbbmGroup(Iterable<String> nbbmArray, String rq) {
        ArrayListMultimap rs = ArrayListMultimap.create();

        rq = rq.replaceAll("-", "");
        try {
            List<HInfo> list = new ArrayList<>();
            for (String nbbm : nbbmArray) {
                nbbm = nbbm.split("_")[1];
                list.addAll(read(nbbm, rq));
            }
            Class clazz = HInfo.class;
            rs = new ConvertUtil().groupMultiList(list, "_", clazz.getDeclaredField("nbbm"), clazz.getDeclaredField("jsy"));
        } catch (Exception e) {
            logger.error("", e);
        }
        return rs;
    }

    /**
     * 根据车辆和日期获取油耗数据,以 车辆 为key
     *
     * @param nbbmArray
     * @param rq
     * @return
     */
    public ArrayListMultimap findByNbbmGroup1(Iterable<String> nbbmArray, String rq) {
        ArrayListMultimap rs = ArrayListMultimap.create();

        rq = rq.replaceAll("-", "");
        try {
            List<HInfo> list = new ArrayList<>();
            for (String nbbm : nbbmArray) {
                list.addAll(read(nbbm, rq));
            }
            Class clazz = HInfo.class;
            rs = new ConvertUtil().groupMultiList(list, "_", clazz.getDeclaredField("nbbm"));
        } catch (Exception e) {
            logger.error("", e);
        }
        return rs;
    }

    public List<HInfo> read(String nbbm, String rq) {
        return redisTemplate.opsForList().range(REDIS_KEY_PREFIX + nbbm + ":" + rq, 0, -1);
    }

    /**
     * 将 list 与redis里的数据合并
     *
     * @param key
     * @param list
     */
    public void mergeData(String key, List<HInfo> list) {
        key = REDIS_KEY_PREFIX + key;

        //更新  直接覆盖更新
        redisTemplate.execute(redisUtils.getUpdateCallback(key, list));
    }

    @Autowired
    ElecRefreshThread elecRefreshThread;

    @Override
    public void run(String... strings) throws Exception {
        Application.mainServices.schedule(new Runnable() {
            @Override
            public void run() {
                //启动加载油耗缓存
                synchData(null);
            }
        }, 30, TimeUnit.SECONDS);


        //定时刷新油耗信息
        Application.mainServices.scheduleWithFixedDelay(elecRefreshThread, 60 * 40, 60 * 40, TimeUnit.SECONDS);
    }

    /**
     * 和数据库同步数据
     */
    public void synchData(Integer days) {
        int cacheDays = Integer.parseInt(ConfigUtil.get("cache.days"));
        if (null != days && days < cacheDays)
            cacheDays = days;
        //设置key 序列化器
        redisTemplate.setKeySerializer(new StringRedisSerializer());

        DateTime dt = new DateTime();
        dt = dt.withHourOfDay(0).withMinuteOfHour(0).withSecondOfMinute(0).minusDays(cacheDays);
        List<HInfo> list = hInfoRepository.findByDateLT(dt.toDate());
        //写入redis
        wirte(list);
        logger.info("刷新氢耗数据, days: " + cacheDays + " -size: " + list.size() + " -LT: " + dt.toString("yyyy-MM-dd"));
    }

    @Component
    public static class ElecRefreshThread extends Thread {

        @Autowired
        HRedisService hRedisService;

        @Override
        public void run() {
            try {
            	hRedisService.synchData(5);
            } catch (Exception e) {
                logger.error("", e);
            }
        }
    }
}