优化redis 分页(二)

这篇文章是将redis 的分页封装好了的

看之前要先对整个存储结构有一个清晰的概念 看懂:http://blog.csdn.net/qq_27292113/article/details/51926891 的图

package redis.test;
 
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import redis.clients.jedis.Jedis;
import redis.util.RedisUtil;
 
public class redisTest { 
    //redis ids集合的 的key名称
    public static    String KEYIDS= "IDS";
    
    // redis 对象的 的key名称  "SYS:BILL:"+"id"  获取单个对象
    public static    String OBJECTKEYID= "OBJECT:";
    
    // list 的主键名称
    public static    String MAJORKEY="id";
    
    //num 当前页数
    public static    Long num = 1l;
    //pageCount 每页条数
    public static    Long pageCount = 10l;
    
    //所有缓存3天后失效
    public static void main(String[] args) {
        //写入数据
        setDateBase();
        
        //读取列表数据
        readDateBase(num,pageCount);
        
        //读取数据单个对象
        readObjectDateBase("0");
    }
 
 
    /**
     * 读取数据
     */
    private static void readDateBase(Long num,Long pageCount) {
        //获取redis对象
        Jedis jedis = new Jedis("localhost");
        try {
            List<Map<String, String>> findPagedQuery = RedisUtil.findPagedQuery(KEYIDS, OBJECTKEYID, num, pageCount, jedis);
            if (findPagedQuery!=null && findPagedQuery.size()>0) {
                System.out.println("查询到当前的数据记录:");
                for (Map<String, String> map : findPagedQuery) {
                    System.out.println(map.toString());
                }
            }else{
                System.out.println("当前页数据为空");
            }
        
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            jedis.close();
        }
    }
    
    /**
     * 读取数据单个对象
     */
    private static void readObjectDateBase(String key) {
        key= OBJECTKEYID+key;
        //获取redis对象
        Jedis jedis = new Jedis("localhost");
        try {
             Map<String, String> hgetAll = jedis.hgetAll(key);
             System.out.println("查询id为:"+key+"的对象结果:");
             System.out.println(hgetAll.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            jedis.close();
        }
    }
    
    
    /**
     * 存入数据源
     */
    public static void setDateBase(){
        Jedis jedis = new Jedis("localhost");
        List<Map<String, Object>> list =new ArrayList<Map<String,Object>>();
        Date d= new Date();
        for (int i = 0; i < 20; i++) {
            Map<String, Object> map =new HashMap<String, Object>();
            map.put(MAJORKEY, i);
            map.put("name", "雄"+i);
            map.put("createDate", d);
            list.add(map);
        }
        try {
            RedisUtil.setCacheObjectInfo(list, KEYIDS, OBJECTKEYID, MAJORKEY, jedis);
            System.out.println("写入数据成功!");
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            jedis.close();
        }
    }
    
    
    
    
    
    
    
     
       
    
}


package redis.util;
 
 
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Response;
 
public class RedisUtil {
 
    //缓存时间
    public static final Integer SECONDS=3*60*60*24;
     
    /**
     * 查询缓存中的数据
     * @param jedis
     * @param keyIds        id集合的key值
     * @param objectKeyId   对象key值的SYS:BILL:前缀  如:"SYS:BILL:"+订单号
     * @param num 当前页数
     * @param pageCount  每页条数
     * @return
     */
    public static  List<Map<String, String>> findPagedQuery(String keyIds, String objectKeyId, Long num, Long pageCount,Jedis jedis) {
        List<Map<String, String>> list = new ArrayList<Map<String, String>>();
         //获取管道对象
        Pipeline pipeline = jedis.pipelined();
        // 开始记录数
        Long startCount = (num - 1) * pageCount;
        List<String> lrange = jedis.lrange(keyIds, startCount, startCount + pageCount - 1);
        if (startCount.intValue() != 0 && lrange.size() != pageCount) {
            // 当缓存中数据不够时直接返回空
            return null;
        }
        // 使用pipeline 批量获取数据
        Map<String, Response<Map<String, String>>> responses = new HashMap<String, Response<Map<String, String>>>();
        for (String key : lrange) {
            String objectKey = objectKeyId + key;
            responses.put(key, pipeline.hgetAll(objectKey));
        }
        // 同步数据
        pipeline.sync();
        for (String key : responses.keySet()) {
            Map<String, String> map = new HashMap<String, String>();
            // 获取订单对象
            map = responses.get(key).get();
            list.add(map);
        }
        return list;
    }
    
    
    
    
    /**
     * 存入对象数据
     * @param list
     * @param keyIds         redis ids集合的 的key名称
     * @param objectKeyId  redis 对象的 的key名称
     * @param majorKey       list 的主键名称
     */
    public static void setCacheObjectInfo(List<Map<String, Object>> list,String keyIds,String objectKeyId,String majorKey, Jedis jedis) {
         //获取管道对象
        Pipeline pipeline = jedis.pipelined();
        jedis.del(keyIds);
        for (Map<String, Object> object : list) {
            //存储 对象 信息
            pipeline.rpush(keyIds, object.get(majorKey).toString());
            //获取封装好的对象数据
            Map<String, String> billMap = getEncapsulationObject(object);
            String key=objectKeyId+object.get(majorKey);
            pipeline.hmset(key, billMap);
            pipeline.expire(key, SECONDS);
        }
        pipeline.expire(keyIds, SECONDS);
        pipeline.sync();
    }
    
 
    /**
     * 将数据转换成字符串
     * @param object
     * @return
     */
    public static Map<String, String> getEncapsulationObject(Map<String, Object> object){
        Map<String, String> billMap = new HashMap<String, String>();
        for(String key:object.keySet()){
            billMap.put(key,convertString(object.get(key)));
        }
        return billMap;
    }
    
    
    
    /**
     * 转换对象
     * 当对象是一个时间类型 转成时间戳
     * 其他类型都为字符串
     * @param object
     * @return
     */
    public static String convertString(Object object){
        Object obj=object;
        if(obj == null){
            return "";
        } else if(obj instanceof Date){
            obj = ((Date)obj).getTime();
            return obj.toString();
        }
        if(isBlank(obj.toString())){
            return "";
        }   
        return obj.toString();
    }
    
    
    /**
     * 判断字符串是否为空
     * @param str
     * @return
     */
    public static boolean isBlank(String str)
    {
        if( str == null || str.length() == 0 )
            return true;
        return false;
    }
}

后续扩展有空时再补充。
这里主要有个redis资源占用的问题,上面的示例代码没有去释放redis对象。如果redis 连接池 连接数比较少会很快消耗掉,导致后面的请求获取不到redis对象。这个一定要注意。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值