Redis分页排序业务详细实现

  最近公司由于业务中需要将帖子,评论,视频等加入缓存,以前没怎么操作过缓存得分页,看了一下源码,这里主要用到redis两个数据类型:SortedSet(Zset)和hash两种数据类型,至于为什么选择这两个后面再说。

SortedSet(Zset)数据类型

 SortedSet(Zset)是有序的集合类型,但是它和LinkedHashSet还不一样,LinkedHashSet维护的是插入时的顺序,而SortedSet维护的是元素之间大小关系的顺序(比如升序、降序等,是根据大小关系来维护顺序的),简单就是说我们可以根据我们需求对其排序,有分页就肯定有排序所以这里我选择的用sortset。    

    这里主要用到该数据类型的Zrevrangebyscore和zadd两种类型,zadd负责向里面插入对应数据,Zrevrangebyscore负责分页。

hash数据类型

 hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象

思路:

    主要思路就是在数组中放入需要分页的key和排序的元素,在hash存放key所对应对象详细信息。

   排序测试

   第一步:向hash中插入数据对象。每一个对象都有一个uuid(为了模拟数据库表对应的主键),同时插入数据时候向SortedSet member属性插入对应对象的uuid和sort插入需要排序的字段(排序的一个属性,这里先用1234排序测试)

    写个测试类测试一下

 public static void main(String[] args) {
        //存数据
        Jedis jedis = new Jedis("ip", "port", 10000);
        jedis.auth("123456");
        jedis.select(9);
        for (int i = 0; i < 10; i++) {
            String s = IdGenerator.generateId();
            for (int j = 10 - i; j > 0; j--) {
                System.out.println(j);
                //数组中存值  j:排序值,s:对应数组里key
                jedis.zadd("list", j, s);
                break;
            }
            Date date = new Date();
            SolrBean solrBean = new SolrBean();
            solrBean.setId(s);
            solrBean.setContent(DateUtil.formatDate(date));
            JSONObject jsonObject = JSONObject.fromObject(solrBean);

            Long test = jedis.hset("test", s, jsonObject.toString());
            boolean d = test >= 0;

        }
        //分页取数据
       Set set = jedis.zrevrangeByScore("list", "+inf", "-inf",2,5);
        System.out.println(set);
    }

测试结果:

    

   设置的是从第二个开始倒叙从大到小查,查询五个,五个对应的对象的id分别是b2cca951b81c437f9d4cf7a2a81f09a8, cf71a2a1a6764e76ad82975be90fdb5b, 28655e95aab34abf9f97399a819c713e, 3ad0375058ba4f699982dc1b1384303d, dd18a190a20d44ad802b96ddce848ee6,可以在图里看到刚好是倒叙排列


实际应用: 

 
  

工具类封装:

                    
package com.citcc4.traffic.common.cache;

import com.alibaba.fastjson.JSONObject;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class VideoInfoCache {
    private static JedisPool jedisPool;

    private int index;

    public VideoInfoCache(JedisPool pool, int index) {
        this.jedisPool = pool;
        this.index = index;
    }

    /**
     * 存值
     * @param key
     * @param imei
     * @param info
     * @return
     */
    public boolean  setVideoInfo(String key,String imei ,VideoInfo info) {
        if (info == null || key == null) {
            return false;
        }
        String json = JSONObject.toJSONString(info);
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.select(index);
            //同时像链表加索引
            Long list = jedis.zadd("video-list:"+imei, info.getUploadTime(), key);
            Long test = jedis.hset("video-info", key, json);
            System.out.println(list + "--------------" + test + "---------key---" + key);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 获取key对应值数量
     * @param imei
     * @return
     */
    public Integer getSize( String imei) {
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.select(index);
            Long zcard = jedis.zcard("video-list:" + imei);
            return zcard.intValue();
        } catch (Exception e) {
        e.printStackTrace();
        }
        return 0;
    }

    /**
     * 分页取值
     * @param limit 每次查几条
     * @param offset 当前页*limit
     * @param imei
     * @return
     */
    public List listVideoInfoWithPage(int limit, int offset, String imei) {
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.select(index);
            Set list = jedis.zrevrangeByScore("video-list:"+imei, "+inf", "-inf", offset, limit);
            List infoList = new ArrayList<>();
            if (list != null && list.size() > 0) {
                Map map = jedis.hgetAll("video-info");
                for (String s : list) {
                    //根据s取值
                    String json = map.get(s);
                    VideoInfo videoInfo = JSONObject.parseObject(json, VideoInfo.class);
                    //注意查询出来值不要在这里筛选,否则出来值会变少,筛选的时候直接在存值时候筛选
                    infoList.add(videoInfo);
                }
            }
            return infoList;
        } catch (Exception e) {
        }
        return null;
    }
}

 
  

代码中应用:

存值:

 @RequestMapping(value = "/moveVideo2Redis", method = RequestMethod.POST)
    public Object moveVideo2Redis() {
        UserOrderInfoEntityExample userOrderInfoEntityExample=new UserOrderInfoEntityExample();
        UserOrderInfoEntityExample.Criteria criteria1 = userOrderInfoEntityExample.createCriteria();
        criteria1.andVideoIdIsNotNull();
        List userOrderInfoEntities = userOrderInfoEntityMapper.selectByExample(userOrderInfoEntityExample);
        List list =new ArrayList<>();
        if (CollectionUtil.isNotEmpty(userOrderInfoEntities)){
            for (UserOrderInfoEntity userOrderInfoEntity : userOrderInfoEntities) {
                list.add(userOrderInfoEntity.getVideoId());
            }
        }
        CapVideoEntityExample capVideoEntityExample=new CapVideoEntityExample();
        CapVideoEntityExample.Criteria criteria = capVideoEntityExample.createCriteria();
        //criteria.andDelFlagEqualTo("0");
        criteria.andVideoIdNotIn(list);
        List capVideoEntities = capVideoEntityMapper.selectByExample(capVideoEntityExample);
        if (CollectionUtil.isNotEmpty(capVideoEntities)){
            for (CapVideoEntity capVideoEntity : capVideoEntities) {
                VideoInfo videoInfo=new VideoInfo();
                videoInfo.setVideoid(capVideoEntity.getVideoId());
                videoInfo.setImei(capVideoEntity.getDeviceId());
                videoInfo.setUrl(capVideoEntity.getVideoFileUrl());
                videoInfo.setAddress(capVideoEntity.getVideoAddress());
                videoInfo.setGps(capVideoEntity.getLocation());
                videoInfo.setUploadTime(capVideoEntity.getSnapEndDate().getTime());
                videoInfo.setVideoSize("25");
                videoInfo.setVideoLength("17");
                VideoInfoCache videoInfoCache=new VideoInfoCache(jedisPool,7);
                if (StringUtils.isNotEmpty(capVideoEntity.getVideoId())){
                    videoInfoCache.setVideoInfo(capVideoEntity.getVideoId(),capVideoEntity.getDeviceId(),videoInfo);
                }
            }
        }
        return new JsonResult(200, null, "修改成功!");
    }

 
  

取值:

@RequestMapping(value = "/v3/video/history/list", method = RequestMethod.GET)
    public Object listAll(HttpServletRequest request,
                          @RequestParam(name = "offset", defaultValue = "0") Integer offset,
                          @RequestParam(name = "limit", defaultValue = "10") Integer limit) {
        // 获取用户信息
        String token = request.getHeader("token");
        JsonResult tokenMesage = (JsonResult) tokenService.checkToken(token);

        if (tokenMesage.getData() == null) {
            return tokenMesage;
        }
        // 获取用户信息
        UserEntity userEntity = (UserEntity) tokenMesage.getData();
        CloudMirrorEntityExample mirrorExample = new CloudMirrorEntityExample();
        CloudMirrorEntityExample.Criteria criteria = mirrorExample.createCriteria();
        criteria.andUserIdEqualTo(userEntity.getUserId());
        // 查询用户绑定云镜信息
        List entityList = null;
        List videoInfos=null;
        int num=0;
        try {
            entityList = userService.findUserMirrorInfo(mirrorExample);
            if (CollectionUtil.isNotEmpty(entityList)){
                String deviceId = entityList.get(0).getDeviceId();
                VideoInfoCache videoInfoCache  =new VideoInfoCache(jedisPool,7);
                videoInfos = videoInfoCache.listVideoInfoWithPage(limit, offset, deviceId);
                num=videoInfoCache.getSize(deviceId);
                logger.info(num);
            }
        } catch (BusinessException e) {
            e.printStackTrace();
            logger.info(e.getMessage());
        }

        return new JsonResult(200,videoInfos,"",num);
    }



你可能感兴趣的:(Redis)