非关系数据库之Redis ----springBoot操作redis入门案例(第八弹)

点赞评论 加关注  不迷路

1、导入对应的jar包。

<!-- 整合redis -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>2.9.0</version>
</dependency>

2、yml文件配置。

#redis配置
redis:
  host: localhost
  port: 6379
  password: 123456
  timeout: 10000ms
  jedis:
    pool:
      max-active: 10
      min-idle: 3
      max-idle: 5

3、创建配置类(重要)

@Configuration
@EnableCaching
public class RedisConfiguration extends CachingConfigurerSupport {

    @Bean
    public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate<Object,Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());//key序列化
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

}

4、入门案例使用;

@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisDemoTest {

    @Resource
    private RedisTemplate<Object,Object> redisTemplate;


    @Test
    public void getRedis(){
        //连接本地的 Redis 服务
        Jedis jedis = new Jedis("localhost");
        System.out.println("连接成功");
        //设置 redis 字符串数据
        jedis.set("str", "Hello Redis");
        // 获取存储的数据并输出
        System.out.println("redis 存储的字符串为: "+ jedis.get("str"));
    }

    @Test
    public void  demo(){
        redisTemplate.opsForValue().set("str","Hello");
        System.out.println("redis 存储的字符串为: "+ redisTemplate.opsForValue().get("str"));
    }

}

spring boot在Spring Data Redis提供了两个模板:

RedisTemplate

StringRedisTemplate

RedisTemplate会使用JdkSerializationRedisSerializer处理数据,这意味着key和value都会通过Java进行序列化。 
StringRedisTemplate默认会使用StringRedisSerializer处理数据。

要是操作字符串的话,用StringRedisTemplate就可以满足。但要是想要存储一个对象Object,我们就需要使用RedisTemplate,并对key采用String序列化方式,对value采用json序列化方式,这时候就需要对redisTemplate自定义配置,项目源码片段:

RedisTempalte类API

方  法

子API接口

描  述

opsForValue()

ValueOperations<K, V>

操作具有简单值的条目

opsForList()

ListOperations<K, V>

操作具有list值的条目

opsForSet()

SetOperations<K, V>

操作具有set值的条目

opsForZSet()

ZSetOperations<K, V>

操作具有ZSet值(排序的set)的条目

opsForHash()

HashOperations<K, HK, HV>

操作具有hash值的条目

boundValueOps(K)

BoundValueOperations<K,V>

以绑定指定key的方式,操作具有简单值的条目

boundListOps(K)

BoundListOperations<K,V>

以绑定指定key的方式,操作具有list值的条目

boundSetOps(K)

BoundSetOperations<K,V>

以绑定指定key的方式,操作具有set值的条目

boundZSet(K)

BoundZSetOperations<K,V>

以绑定指定key的方式,操作具有ZSet值(排序的set)的条目

boundHashOps(K)

BoundHashOperations<K,V>

以绑定指定key的方式,操作具有hash值的条目

5、spring boot缓存管理

spring boot集成redis进行数据缓存功能;有两种实现:

1,通过在代码中调用redis API实现数据的CRUD;

【参考RedisUtils工具类,该工具类支持redis的其他业务场景】

2,通过在方法上添加缓存注解实现;

【重点介绍,只支持redis作为缓存管理时使用】

Spring 提供了很多缓存管理器,例如:

SimpleCacheManager

EhCacheCacheManager

CaffeineCacheManager

GuavaCacheManager

CompositeCacheManager

RedisCacheManager Spring Data提供的缓存管理器:RedisCacheManager

在Spring Boot中通过@EnableCaching注解自动化配置合适的缓存管理器(CacheManager),默认情况下Spring Boot根据下面的顺序自动检测缓存提供者:

Generic

JCache (JSR-107)

EhCache 2.x

Hazelcast

Infinispan

Redis

Guava

Simple

因为之前已经配置了RedisTemplate了,Spring Boot就无法自动给RedisCacheManager设置RedisTemplate了,所以要自己配置CacheManager。

1, 修改RedisConfig配置类,添加@EnableCaching注解,并继承CachingConfigurerSupport,重写CacheManager 方法:

/**

 * 实例化 CacheManager 对象,指定使用RedisCacheManager作缓存管理

 *

 * @return CacheManager

 */

@Bean

public CacheManager cacheManager(RedisTemplate redisTemplate) {

    RedisCacheManager rcm = new RedisCacheManager(redisTemplate);

    // 设置缓存过期时间(单位:秒),60秒

    rcm.setDefaultExpiration(120);

    return rcm;

}

Spring提供了如下注解来声明缓存规则:

@Cacheable triggers cache population

@cacheevict triggers cache eviction

@cacheput updates the cache without interfering with the method execution

@caching regroups multiple cache operations to be applied on a method

@cacheconfig shares some common cache-related settings at class-level

注 解

描 述

@Cacheable

表明Spring在调用方法之前,首先应该在缓存中查找方法的返回值。如果这个值能够找到,就会返回缓存的值。否则的话,这个方法就会被调用,返回值会放到缓存之中

@cacheput

表明Spring应该将方法的返回值放到缓存中。在方法的调用前并不会 检查缓存,方法始终都会被调用

@cacheevict

表明Spring应该在缓存中清除一个或多个条目

@caching

这是一个分组的注解,能够同时应用多个其他的缓存注解

@cacheconfig

可以在类层级配置一些共用的缓存配置

@Cacheable和@cacheput有一些共有的属性:

属  性

类  型

描  述

value

String[]

要使用的缓存名称

condition

String

SpEL表达式,如果得到的值是false的话,不会将缓存应用到方法调用上

key

String

SpEL表达式,用来计算自定义的缓存key

unless

String

SpEL表达式,如果的值得到是true的话,返回值不会放到缓存之中

2, 通过注解@Cacheable,对数据进行缓存处理:

代码片段:

/**

     * 通过缓存注解,添加数据到redis中

     * </br>实现数据缓存!

     * @param cat 对象

     */

    @Cacheable

    @RequestMapping(value = "/getCat/{catId}", method = RequestMethod.GET)

    @ResponseBody

    public Cat add(@PathVariable("catId") int catId){

        return this.catService.getCat(catId);

}

注意:Cat对象必须实现implements Serializable接口!

java.lang.IllegalStateException: No cache could be resolved for 'Builder[public com.wyait.redis.pojo.Cat com.wyait.redis.controller.RedisCacheController.add(int)] caches=[] | key='' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'' using resolver 'org.springframework.cache.interceptor.SimpleCacheResolver@5e67a11d'. At least one cache should be provided per cache operation.  at org.springframework.cache.interceptor.CacheAspectSupport.getCaches(CacheAspectSupport.java:244) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]

这个错误,是由于@Cacheable注解没有指定缓存名称导致的。加上value值,再试:

@Cacheable(value = "catCache")

测试访问成功!多次访问,走redis缓存。

3, redis缓存key生成策略

键的生成策略有两种,一种是默认策略,一种是自定义策略。

----------------------------默认策略:

If no params are given, return SimpleKey.EMPTY.

If only one param is given, return that instance.

If more the one param is given, return a SimpleKey containing all parameters.

默认的key是通过KeyGenerator生成的,其默认策略如下:

1.如果方法没有参数,则使用0作为key;

2.如果只有一个参数的话则使用该参数作为key;

3.如果参数多于一个则使用所有参数的hashcode作为key;

----------------------------自定义策略:

自定义策略是指我们通过Spring的EL表达式来指定我们的key。这里的EL表达式可以使用参数以及它们对应的属性。使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”。

之前在redisTemplate里设置了template.setKeySerializer(new StringRedisSerializer()),需要key是string类型。也可以使用SpEL表达式生成Key,

(SpEL表达式:http://itmyhome.com/spring/expressions.html)

返回结果需要是string类型(比如#root.methodName就是,#root.method不是String),通用办法是重写keyGenerator定制Key默认生成策略(按照缓存名称+id方式生成key,同时确保更新操作的时候,操作的是同一条数据),也可以在使用缓存注解时指定key:

/**

     * 指定key的生成策略

     * @return KeyGenerator

     */

    @Bean public KeyGenerator keyGenerator() {

        return new KeyGenerator() {

            @Override public Object generate(Object target, Method method,

                    Object... params) {

                StringBuilder sb = new StringBuilder();

                String[] value = new String[1];

                // sb.append(target.getClass().getName());

                // sb.append(":" + method.getName());

                Cacheable cacheable = method.getAnnotation(Cacheable.class);

                if (cacheable != null) {

                    value = cacheable.value();

                }

                CachePut cachePut = method.getAnnotation(CachePut.class);

                if (cachePut != null) {

                    value = cachePut.value();

                }

                CacheEvict cacheEvict = method.getAnnotation(CacheEvict.class);

                if (cacheEvict != null) {

                    value = cacheEvict.value();

                }

                sb.append(value[0]);

                //获取参数值

                for (Object obj : params) {

                    sb.append(":" + obj.toString());

                }

                return sb.toString();

            }

        };

    }

注意:

1,在使用缓存注解时,也可以指定统一规则的key

(比如:@Cacheable(value = "catCache", key = "#root.caches[0].name + ':' + #id"));

就可以不走KeyGenerator默认规则;同样可以实现,更新和查询都是同一个key的数据;

2,使用注解进行数据缓存,指定数据过期时间需要百度普及下!

4, 更新缓存数据

更新与删除Redis缓存需要用到@cacheput和@cacheevict。必须保证keyGenerator生成同一个key,否则更新的不是同一条的数据;

/**

     * 更新redis中的缓存数据

     *</br> #root. 是spEL表达式

     * </br>如果参数是个对象,就通过“#对象.变量”获取到对应的key中需要的值;比如:#cat.id

     * @param id 主键

     */

    @CachePut(value = "catCache", key = "#root.caches[0].name + ':' + #id")

    @RequestMapping(value = "/updateCat", method = RequestMethod.POST)

    @ResponseBody

    public Cat update(@RequestParam int id){

        System.out.println("==========请求参数:"+id);

        return this.catService.updateCat(id);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学跑的猿

制作不易

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值