//redis中的key进行字符串序列化 redisTemplate.setKeySerializer(new StringRedisSerializer()); //首先去redis缓存中判断是否有值 Double historyAverageRate = (Double) redisTemplate.opsForValue().get(Constant.HISTORY_AVERAGE_RATE); //解决缓存穿透问题:使用了两次判断与加锁,其主要目的就是只让一个线程访问数据库,其他的线程都让他们从缓存中获取数据 //第一次的判断缓存中是否有数据,就可以将多个一起访问的线程提取出来 //然后就通过加锁,只让一个线程访问数据库,这个线程会把数据写到缓存中 //最后进行第二次判断缓存中是否有数据(肯定有,因为第一个拿到锁的进程已经将数据放到缓存中了),这样其它进程都从缓存中获取了数据 //没有值就去数据库中查找,然后放到redis缓存中 if (!ObjectUtils.allNotNull(historyAverageRate)){ //如果为空,进行加锁 synchronized (this){ //再次从缓存中获取值进行判断 historyAverageRate = (Double) redisTemplate.opsForValue().get(Constant.HISTORY_AVERAGE_RATE); if (!ObjectUtils.allNotNull(historyAverageRate)){ System.out.println("从数据库中查询数据"); historyAverageRate = loanInfoMapper.selectHistoryAverageRate(); redisTemplate.opsForValue().set(Constant.HISTORY_AVERAGE_RATE, historyAverageRate, 15, TimeUnit.SECONDS); }else { System.out.println("从redis中查询"); } } }else { System.out.println("从redis中查询"); } return historyAverageRate;