redis实现计数--------Redis increment

  经理提出新的需求,需要知道每天微信推送了多少条模板消息,成功多少条,失败多少条,想到用Redis缓存,网上查了一些资料,Redis中有方法increment,测试代码如下

  

Controller

import javax.annotation.Resource;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/** 
 * @author wangqq 
 * @version 创建时间:2018年8月10日 下午2:30:47 
 * 类说明 
 */
@Controller
@RequestMapping("test")
public class TestController {
    
    @Resource
    private TestService testService;
    
    @RequestMapping("testRedis")
    @ResponseBody
    public int testRedis (){
        return testService.testRedis ();
    }
}

Service

import javax.annotation.Resource;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

/** 
 * @author wangqq 
 * @version 创建时间:2018年8月10日 下午2:32:13 
 * 类说明 
 */
@Service
public class TestService {
    
    @Resource
    RedisTemplate<String,Object> redisTemplate;
    
    @Resource(name="redisTemplate")
    private ValueOperations<String,Object> ops;
    
    public int testRedis() {
        try {
            //此方法会先检查key是否存在,存在+1,不存在先初始化,再+1
            ops.increment("success", 1);
            
            return (int) ops.get("success");
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        
        return 0 ;
    }
    
}

直接使用ops.get("success"),会出现错误,报错信息 Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.EOFException。 根据信息,可以看到是反序列化出错,上网查一下,貌似是因为JDK序列化之后,反序列化失败。解决办法:

第一种解决办法

用 redisTemplate.boundValueOps("success").get(0, -1)获得key值

import javax.annotation.Resource;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

/** 
 * @author wangqq 
 * @version 创建时间:2018年8月10日 下午2:32:13 
 * 类说明 
 */
@Service
public class TestService {
    
    @Resource
    RedisTemplate<String,Object> redisTemplate;
    
    @Resource(name="redisTemplate")
    private ValueOperations<String,Object> ops;
    
    public int testRedis() {
        try {
            //此方法会先检查key是否存在,存在+1,不存在先初始化,再+1
            ops.increment("success", 1);
            
            //return (int) ops.get("success");
            
            return Integer.valueOf(redisTemplate.boundValueOps("success").get(0, -1));
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        
        return 0 ;
    }
    
}

页面显示为2,因为第一次已经成功了,只是get失败了

第二种解决办法

添加一个方法 getKey

import javax.annotation.Resource;

import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Service;

/** 
 * @author wangqq 
 * @version 创建时间:2018年8月10日 下午2:32:13 
 * 类说明 
 */
@Service
public class TestService {
    
    @Resource
    RedisTemplate<String,Object> redisTemplate;
    
    @Resource(name="redisTemplate")
    private ValueOperations<String,Object> ops;
    
    public int testRedis() {
        try {
            //此方法会先检查key是否存在,存在+1,不存在先初始化,再+1
            ops.increment("success", 1);
            
            //return (int) ops.get("success");
            
            //return Integer.valueOf(redisTemplate.boundValueOps("success").get(0, -1));
            
            return (int) getKey("success");
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        
        return 0 ;
    }
    
    public long getKey(final String key) {
        
        return redisTemplate.execute(new RedisCallback<Long>() {
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                
                RedisSerializer<String> redisSerializer = redisTemplate.getStringSerializer();
                
                byte[] rowkey = redisSerializer.serialize(key);
                byte[] rowval = connection.get(rowkey);
                
                try {
                    String val = redisSerializer.deserialize(rowval);
                    return Long.parseLong(val);
                } catch (Exception e) {
                    return 0L;
                }
            }
        });
    }
    
}

页面返回

 

 最后一步,设置每天零点过期,重新计数

//当天时间
Date date = new Date();
//当天零点
date = DateUtils.truncate(date, Calendar.DAY_OF_MONTH);
//第二天零点
date = DateUtils.addDays(date, +1);

redisTemplate.expireAt("success", date);
原文地址:https://www.cnblogs.com/Cassie-wang/p/9455134.html