SpringBoot 集成 redis

SpringBoot 集成 redis

1.在pom.xml文件中配置redis的相关依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2.在SpringBoot 的配置文件application中添加redis配置

spring.redis.host=127.0.0.1
#Redis服务器连接端口
spring.redis.port=6379
#Redis服务器连接密码(默认为空)
spring.redis.password=
#连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
#连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.pool.max-idle=8
#连接池中的最小空闲连接
spring.redis.pool.min-idle=0
#连接超时时间(毫秒)
spring.redis.timeout=30000

3.注入 RedisTemplate

配置完成 1 、2 步之后,SpringBoot就帮我们自动配置了 RedisTemplate 这个redis模板类了。只需在需要操作redis的类中注入 RedisTemplate:

@Autowired
private RedisTemplate<String,String> redisTemplate;

@Autowired
private RedisTemplate<Object,Object> redisTemplate;

注意: 1.SpringBoot帮我们注入的 RedisTemplate 类,泛型只能写<String,String> 、<Object,Object>
2.实体类需要 实现 Serializer 类。才能进行序列化的数据存储到 redis 中。

4.演示代码

public class StudentServiceImpl implements StudentService{
    //注入 持久层 类 用于调动数据库
    @Autowired
    private StudentMapper studentMapper;
    
    //注入 redis 提供的模板类(引入pom 配置好 application IOC中就会有这个类)
    @Autuwired
    private RedisTemplate<Object,Object> redisTemplate;
    
    /**
        获取学生列表的类
    */
    public List<Student> getAllStudent(){
        //1.设置序列化后的key能正常显示,而不是显示的序列化后似乱码的样式
        //(1)RedisSerializer类是 redis的序列化器   StringRedisSerializer类 将结果序列化成可读性        //强的字符串的序列化信息。(字符串的序列化器)
        RedisSerializer redisSerializer = new StringRedisSerializer();
        //(2)设置字符串的序列化将 key 值序列化成字符串
        redisTemplate.setKeySerializer(redisSerializer);
        
        //查询缓存
        List<Student> studentList = redisTemplate.opsForValue().get("allStudent");
        
        //判断缓存中是否有 上述指定的 key "allStudent" 查询的数据。没有的话,则查询数据库
        if(null == studentList){
            //查询数据库
            studentList = studentMapper.getAllStudent();
            //将查询数据库得到的数据,存入缓存 redis 库中  set(key的名称,value值)
            redisTemplate.opsForValue().set("allStudent",studentList);
        }
        return studentList;
    }
}

(1) 上述代码的问题解析

在请求量很大的情况下(也就是高并发时),上述代码就有 "缓存穿透" 的问题产生了。
"缓存穿透": 就是说,在实际的场景中,我们预想的是 第一个人进行访问后,将数据存到 redis 中,接下来进来的人直接 读取 redis 缓存中的数据。但是在高并发的情况下,这种预想就有问题了。当并发在1W+ 或者更高的时候,第一次进来访问的人可能就不只是一个人了,所以就造成了很多人访问没有走缓存而是走的关系型数据库查询。这种情况就是"缓存穿透"。

解决方法:
  方法一: 在方法上添加 线程锁 关键字 synchronized
    public synchronized List<Student> getAllStudent(){}
  方法二: 在代码逻辑中使用 双重锁机制:  
public class StudentServiceImpl implements StudentService{
    //注入 持久层 类 用于调动数据库
    @Autowired
    private StudentMapper studentMapper;
    
    //注入 redis 提供的模板类(引入pom 配置好 application IOC中就会有这个类)
    @Autuwired
    private RedisTemplate<Object,Object> redisTemplate;
    
    /**
        获取学生列表的类
    */
    public List<Student> getAllStudent(){
        RedisSerializer redisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(redisSerializer);
        
        List<Student> studentList = redisTemplate.opsForValue().get("allStudent");
        //双重检测锁
        if(null == studentList){
            studentList = redisTemplate.opsForValue().get("allStudent");
            synchronized(this){
                if(null == studentList){
                    studentList = studentMapper.getAllStudent();
                    redisTemplate.opsForValue().set("allStudent",studentList);
                }
            }
        }
        
        return studentList;
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容