SpringBoot整合Redis案例缓存首页数据、缓解数据库压力
阅读原文时间:2023年07月08日阅读:1

一、硬编码方式

1、场景

由于首页数据变化不是很频繁,而且首页访问量相对较大,所以我们有必要把首页数据缓存到redis中,减少数据库压力和提高访问速度。

2、RedisTemplate

Jedis是Redis官方推荐的面向Java的操作Redis的客户端,而RedisTemplate是Spring Data Redis中对Jedis api的高度封装。

Spring Data Redis是spring大家族的一部分,提供了在srping应用中通过简单的配置访问redis服务,对reids底层开发包(Jedis, JRedis, and RJC)进行了高度封装,RedisTemplate提供了redis各种操作、异常处理及序列化功能,支持发布订阅,并对spring cache进行了实现。

3、 引入redis

<!-- spring boot redis缓存引入 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- lecttuce 缓存连接池-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

4、添加redis连接配置

spring:
  redis:
    host: ip
    port: 端口号(默认6379)
    database: 1
    password:  #默认为空
    lettuce:
      pool:
        max-active: 20  #最大连接数,负值表示没有限制,默认8
        max-wait: -1    #最大阻塞等待时间,负值表示没限制,默认-1
        max-idle: 8     #最大空闲连接,默认8
        min-idle: 0     #最小空闲连接,默认0

5、 配置Redis

/**
 * 我们自定义一个 RedisTemplate,设置序列化器,这样我们可以很方便的操作实例对象。
 * 否则redis自动使用对象的jdk序列化
 */
@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Serializable> redisTemplate(LettuceConnectionFactory connectionFactory) {
        RedisTemplate<String, Serializable> redisTemplate = new RedisTemplate<>();
        redisTemplate.setKeySerializer(new StringRedisSerializer());//key序列化方式
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());//value序列化
        redisTemplate.setConnectionFactory(connectionFactory);

        return redisTemplate;
    }
}

6、测试redisTemplate

/**
     * 查询缓存中是否存在需要的数据 hasKey
     * 如果缓存中不存在则从数据库中取出数据,并将数据存入缓存 set
     * 如果缓存存在则从缓存中读取数据 get
     * @param ad
     * @return
     */
    @PostMapping("/save-test")
    public R saveAd(@RequestBody Ad ad) {
        // 使用RedisTemplate
        ValueOperations operations = redisTemplate.opsForValue();
        operations.set("index::myad", ad);
        return R.ok();
    }

    @GetMapping("/get-test/{key}")
    public R getAd(@PathVariable("key")String key) {
        // 使用RedisTemplate
        ValueOperations operations = redisTemplate.opsForValue();
        Ad ad = (Ad) operations.get(key);
        return R.ok().data("ad", ad);
    }

    @GetMapping("/delete-test/{key}")
    public R removeAd(@PathVariable("key")String key) {
        Boolean result = redisTemplate.delete(key);
        System.out.println(result);// true
        Boolean isKey = redisTemplate.hasKey(key);
        System.out.println(isKey);// false
        return R.ok();
    }

二、 使用缓存注解

1、修改Redis配置类

配置类上添加注解 :@EnableCaching

2、添加配置Bean

@Bean
public CacheManager cacheManager(LettuceConnectionFactory connectionFactory) {

    RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
        //过期时间600秒
        .entryTtl(Duration.ofSeconds(600))
        // 配置序列化
        .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
        .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
        .disableCachingNullValues();

    RedisCacheManager cacheManager = RedisCacheManager.builder(connectionFactory)
        .cacheDefaults(config)
        .build();
    return cacheManager;
}

3、添加缓存注解

@Cacheable(value = "xxx", key = "'xxx'"):标注在方法上,对方法返回结果进行缓存。下次请求时,如果缓存存在,则直接读取缓存数据返回;如果缓存不存在,则执行方法,并把返回的结果存入缓存中。一般用在查询方法上。

/**
     * 查询缓存中是否存在需要的数据 hasKey
     * 如果缓存中不存在则从数据库中取出数据,并将数据存入缓存 set
     * 如果缓存存在则从缓存中读取数据 get
     * @param adTypeId
     * @return
     */
@Cacheable(value = "index",key = "'selectByAdTypeId'")
@Override
public List<Ad> selectByAdTypeId(String adTypeId) {
    QueryWrapper<Ad> wrapper = new QueryWrapper<>();
    wrapper.orderByAsc("sort");
    wrapper.eq("type_id", adTypeId);
    return baseMapper.selectList(wrapper);
}

@Cacheable(value = "index",key = "'selectHotCourse'")
@Override
public List<Course> selectHotCourse() {
    QueryWrapper<Course> courseQueryWrapper = new QueryWrapper<>();
    courseQueryWrapper.orderByDesc("view_count");
    courseQueryWrapper.last("limit 8");
    return baseMapper.selectList(courseQueryWrapper);
}

@Cacheable(value = "index",key = "'selectHotTeacher'")
@Override
public List<Teacher> selectHotTeacher() {
    QueryWrapper<Teacher> courseQueryWrapper = new QueryWrapper<>();
    courseQueryWrapper.orderByDesc("sort");
    courseQueryWrapper.last("limit 4");
    return baseMapper.selectList(courseQueryWrapper);
}