SpringBoot整合Redis,RedisTemplate和注解两种方式的使用

1.注解方式使用 Redis 缓存

使用缓存有两个前置步骤

  1. pom.xml 引入依赖

    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 整合redis -->
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!-- springboot测试 -->
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-test</artifactId>
    	<scope>test</scope>
    </dependency>
    
  2. 在启动类上加注解 @EnableCaching

    @SpringBootApplication
    @EnableCaching
    public class RedisApplication {
          
          
        public static void main(String[] args) {
          
          
            SpringApplication.run(RedisApplication.class, args);
        }
    }
    

常用的注解有以下几个@Cacheable、@CachePut、@CacheEvict

1.1 添加缓存

缓存的key就是配置在注解里面的值product::123,值是你方法的返回值,如果没有返回值,值就是org.springframework.cache.support.NullValue

在需要加缓存的方法上添加注解 @Cacheable(cacheNames = "product", key = "123"),

cacheNameskey 都必须填,如果不填 key ,默认的 key 是当前的方法名,更新缓存时会因为方法名不同而更新失败。

如在订单列表上加缓存

    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @Cacheable(cacheNames = "product", key = "123")
    public List<Product> list() {
    
    

        List<Product> products=new ArrayList<>();
        for (int i = 0; i < 3; i++) {
    
    
            Product product=new Product();
            product.setId(i+1);
            product.setName("第"+(i+1)+"件商品");
            product.setPrice((double) ((i+1)*100));
            products.add(product);
        }
        return products;
    }

可能会报错,原因是对象未序列化。让对象实现 Serializable 方法即可。

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Product implements Serializable {
    
    
    
    private Integer id;
    private String name;
    private Double price;
}

重启项目访问订单列表,在 rdm 里查看 Redis 缓存,有 product::123 说明缓存成功。

1.2 更新缓存

在需要更新缓存的方法上加注解: @CachePut(cacheNames = "product", key = "123")

注意

  1. cacheNameskey 要跟 @Cacheable() 里的一致,才会正确更新。
  2. @CachePut()@Cacheable() 注解的方法返回值要一致

1.3 删除缓存

在需要删除缓存的方法上加注解:@CacheEvict(cacheNames = "product", key = "123"),执行完这个方法之后会将 Redis 中对应的记录删除。

1.4 其他常用功能

  1. cacheNames 也可以统一写在类上面, @CacheConfig(cacheNames = "product") ,具体的方法上就不用写啦。

    @RestController
    @CacheConfig(cacheNames = "product")
    public class ProdectController {
          
          }
    
  2. Key 也可以动态设置为方法的参数

    	@GetMapping("/detail")
        @Cacheable(cacheNames = "product", key = "#id")
        public Product detail(@RequestParam("id") Integer id){
          
          
            if (id==1){
          
          
                return new Product(1,"电冰箱",20d);
            }else if (id==2){
          
          
                return new Product(2,"洗衣机",30d);
            }else {
          
          
                return new Product(3,"彩电",40d);
            }
        }
    

    如果参数是个对象,也可以设置对象的某个属性为 key。比如其中一个参数是 user 对象,key 可以写成 key="#user.id"

  3. 缓存还可以设置条件。

    设置当 openid 的长度大于3时才缓存

    	@GetMapping("/detailOnCondition")
        @Cacheable(cacheNames = "product", key = "#id", condition = "#id > 2")
        public void detail(@RequestParam("id") String id){
          
          
            System.out.println("id是"+id);
        }
    

    还可以指定 unless即条件不成立时缓存。#result 代表返回值,意思是当返回码不等于 0 时不缓存,也就是等于 0 时才缓存。

    	@GetMapping("/detailOnConditionAndUnless")
        @Cacheable(cacheNames = "product", key = "#id", condition = "#id > 2", unless = "#result!= 0")
        public Integer detailOnConditionAndUnless(@RequestParam("id") Integer id){
          
          
            if (id==3){
          
          
                return 0;
            }else {
          
          
                return 1;
            }
        }
    

##2.RedisTemplate 使用 Redis 缓存

与使用注解方式不同,注解方式可以零配置,只需引入依赖并在启动类上加上 @EnableCaching 注解就可以使用;而使用 RedisTemplate 方式麻烦些,需要做一些配置。

2.1 Redis 配置

第一步还是引入依赖和在启动类上加上 @EnableCaching 注解。

然后在 application.yml 文件中配置 Redis

spring:
  redis:
    port: 6379
    database: 0
    host: 127.0.0.1
    password:
    jedis:
      pool:
        max-active: 8
        max-wait: -1ms
        max-idle: 8
        min-idle: 0
    timeout: 5000ms

然后写个 RedisConfig.java 配置类

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import java.net.UnknownHostException;


@Configuration
public class RedisConfig {
    
    

    @Bean
    @ConditionalOnMissingBean(name = "redisTemplate")
    public RedisTemplate<String, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
    
    

        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(redisConnectionFactory);
        template.setKeySerializer(jackson2JsonRedisSerializer);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashKeySerializer(jackson2JsonRedisSerializer);
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    @ConditionalOnMissingBean(StringRedisTemplate.class)
    public StringRedisTemplate stringRedisTemplate(
            RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
    
    
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}

Redis 的配置就完成了。

使用方式

package io.redis.demo;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

/**
 * @Date: 2019/5/4 下午12:23
 * @Version 1.0
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class RedisTemplateTest {
    
    

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Test
    public void test1(){
    
    
        redisTemplate.opsForValue().set("name","zhangsan");
        String name = (String)redisTemplate.opsForValue().get("name");
        System.out.println(name);
    }

    @Test
    public void test2(){
    
    
        stringRedisTemplate.opsForValue().set("name","zhangsan");
        String name = stringRedisTemplate.opsForValue().get("name");
        System.out.println(name);
    }

    @Test
    public void test3(){
    
    
        redisTemplate.opsForHash().put("produce","1","电视机");
        redisTemplate.opsForHash().put("produce","2","冰箱");
        redisTemplate.opsForHash().put("produce","3","彩电");
        redisTemplate.opsForHash().put("produce","4","自行车");

        String name = (String) redisTemplate.opsForHash().get("produce", "4");
        System.out.println(name);
    }
    @Test
    public void test4(){
    
    
        redisTemplate.opsForList().leftPush("name","zhangfei");
        redisTemplate.opsForList().leftPush("name","liubei");
        redisTemplate.opsForList().leftPush("name","guanyu");
        List names = redisTemplate.opsForList().range("name", 0, -1);
        for (Object name : names) {
    
    
            System.out.println(name);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_38279833/article/details/115446265