Spring集成redis缓存

redis一般使用key--value的形式存值,将内存中的数据保存在磁盘中(in-memory),启动的时候再加载使用。

redis是单进程单线程,支持主从模式。具有会话缓存功能,具有发布/订阅功能。

Redis的LRU策略:

Redis在缓存的内存达到极限时,会优先选择最久未被访问的数据进行回收。具体回收策略通过maxmemory-policy配置项进行配置。

Redis优点:

1.性能好,redis中的数据读写速度快。

2.数据类型丰富,Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型

3.丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性

4.Redis支持数据的备份,即master-slave模式的数据备份

Spring集成Redis:


	
		
			
				classpath:db.properties
			
		
	

	
	

	
	
		
		
		
		
		
		
	

	
	
		
		
		
	

	
	
		
		
			
		
	

	
	
		
		
			
		
		
	        
	    
	

	
	
		
		
		
	

在数据库配置文件中打开缓存:

      
        
        
        
        
          
      

在MVC配置文件中初始化数据库配置:

	
	
	
	

Redis分布式锁:

public interface DistributionLock {
	//加锁成功 返回加锁时间
    public Long lock(String lockKey, String threadname);

    //解锁 需要更加加锁时间判断是否有权限
    public void unlock(String lockKey, long lockvalue, String threadname);

}
public class RedisDistributionLock implements DistributionLock{
	@Autowired
	private RedisTemplate redisTemplate;
	
	 private static final long LOCK_TIMEOUT = 60 * 1000; //加锁超时时间 单位毫秒  意味着加锁期间内执行完操作 如果未完成会有并发现象

	    private static final Logger LOG = Logger.getLogger(RedisDistributionLock.class); //redis锁日志


	    /**
	     * 取到锁加锁 取不到锁一直等待直到获得锁
	     */
	    @Override
	    public synchronized Long lock(String lockKey, String threadname) {
	        LOG.info(threadname + "开始执行加锁");
	        while (true) { //循环获取锁
	            Long lock_timeout = System.currentTimeMillis() + LOCK_TIMEOUT + 1; //锁时间
	            if (redisTemplate.execute(new RedisCallback() {

	                @Override
	                public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
	                    JdkSerializationRedisSerializer jdkSerializer = new JdkSerializationRedisSerializer();
	                    byte[] value = jdkSerializer.serialize(lock_timeout);
	                    return connection.setNX(lockKey.getBytes(), value);
	                }
	            })) { //如果加锁成功
	                LOG.info(threadname + "加锁成功+1");
	                redisTemplate.expire(lockKey, LOCK_TIMEOUT, TimeUnit.MILLISECONDS); //设置超时时间,释放内存
	                return lock_timeout;
	            }else {
	                Long currt_lock_timeout_Str = (Long) redisTemplate.opsForValue().get(lockKey); // redis里的时间
	                if (currt_lock_timeout_Str != null && currt_lock_timeout_Str < System.currentTimeMillis()) { //锁已经失效
	                    // 判断是否为空,不为空的情况下,说明已经失效,如果被其他线程设置了值,则第二个条件判断是无法执行

	                    Long old_lock_timeout_Str = (Long) redisTemplate.opsForValue().getAndSet(lockKey, lock_timeout);
	                    // 获取上一个锁到期时间,并设置现在的锁到期时间
	                    if (old_lock_timeout_Str != null && old_lock_timeout_Str.equals(currt_lock_timeout_Str)) {
	                        // 如过这个时候,多个线程恰好都到了这里,但是只有一个线程的设置值和当前值相同,他才有权利获取锁
	                        LOG.info(threadname + "加锁成功+2");
	                        redisTemplate.expire(lockKey, LOCK_TIMEOUT, TimeUnit.MILLISECONDS); //设置超时时间,释放内存
	                        return lock_timeout;//返回加锁时间
	                    }
	                }
	            }

	            try {
	                LOG.info(threadname +  "等待加锁,睡眠100毫秒"); 
	                TimeUnit.MILLISECONDS.sleep(100);//睡眠100毫秒
	            } catch (InterruptedException e) {
	                e.printStackTrace();
	            } 
	        }
	    }

	    @Override
	    public synchronized void unlock(String lockKey, long lockvalue, String threadname) {
	        LOG.info(threadname + "执行解锁==");//正常直接删除 如果异常关闭判断加锁会判断过期时间
	        Long currt_lock_timeout_Str = (Long) redisTemplate.opsForValue().get(lockKey); // redis里的时间

	        if (currt_lock_timeout_Str != null && currt_lock_timeout_Str == lockvalue) {//如果是加锁者 则删除锁 如果不是则等待自动过期 重新竞争加锁
	            redisTemplate.delete(lockKey); //删除键
	            LOG.info(threadname + "解锁成功---");
	        }
	    }

}


RedisTemplate操作:

public class RedisUnitTest extends BaseJunit4 {
	
	/**
	 * 默认采用String序列化策略(key与value)
	 */
	@Resource(name = "redisTemplate_KVString")
	private RedisTemplate redisTemplate_KVString;
	
	/**
	 * Redis 可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为
	 * String(字符串)、List(列表)、Set(集合)、Hash(散列)和 Zset(有序集合)
	 * Key值如无特殊要求,一般为String类型
	 * 
	 */
	public void queryRedisValue(){
		String key = "";
		String value = "";
		String value2 = "";
		Map maps = new HashMap();
        maps.put("key1","value1");
        maps.put("key2","value2");
        maps.put("key3","value3");
        
        List keys = new ArrayList();
        keys.add("key1");
        keys.add("key2");
        keys.add("key3");
        
		redisTemplate_KVString.opsForValue().set(key, value, 10, TimeUnit.SECONDS);//设置key-value失效时间10s
		redisTemplate_KVString.opsForValue().get(key);//根据key获取value,10秒的时限
		redisTemplate_KVString.opsForValue().setIfAbsent(key, value);//false 已存在key/ true 之前不存在key
		redisTemplate_KVString.opsForValue().multiSet(maps);//同时设置多个 key-value
		redisTemplate_KVString.opsForValue().getAndSet(key, value2);//设置key的value值,并返回旧value
		redisTemplate_KVString.opsForValue().multiGet(keys);//同时取出多个 key对应的value
		redisTemplate_KVString.opsForValue().append(key, value);//key存在则将value追加到末尾,不存在则创建一个key-空串,再加到末尾
		redisTemplate_KVString.opsForValue().get(key, 0, 3);//截取key 所对应的value字符串
		redisTemplate_KVString.opsForValue().size(key);//返回key对应的value长度
		
		redisTemplate_KVString.opsForHash();//操作hash
		redisTemplate_KVString.opsForList();//操作list
		redisTemplate_KVString.opsForSet();//操作set
		redisTemplate_KVString.opsForZSet();//操作有序set
		
		//如需将key在redis服务器中保存为文件夹类型,在文件夹名后加 : 号
		String folder = "key:";
		key = folder + 1;
		redisTemplate_KVString.opsForValue().set(key, value);
	}
}






你可能感兴趣的:(Spring集成redis缓存)