首页 > 数据库 >springCache整合redis详细讲解和配置

springCache整合redis详细讲解和配置

时间:2023-03-02 09:45:02浏览次数:41  
标签:缓存 springCache redis user key 讲解 return public

SpringCache的简介

缓存,就是将数据从数据库等数据来源获取数据,将数据缓存在内存或其他设备如Redis中,为了二次查询能够快速高效的响应结果.

Spring Cache是3.1开始提供, 通过注解的形式,对于整合业务代码友好.

Spring Cache特点:

提供Cache通用入口 ,方便多种实现切换缓存源,如Redis,Guava Cache等
支持事务, 即事务回滚时,缓存同时自动回滚

Cache-redis环境搭建

1.依赖配置
 <!-- Cache基础依赖 -->
<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- 使用  redis  -->
<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.application配置
#redis
  redis:
    host: 43.139.54.197
    port: 6370
    password: '123456'
    database: 0
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0
        max-wait: 1000ms #连接等待时间
      debug: true

Cache的注解

  1. @EnableCaching

    使用场景:在启动类注解@EnableCaching开启缓存 

    @SpringBootApplication
    @EnableCaching  //开启缓存
    public class DemoApplication{
    
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    }
    
  2. @Cacheable

    使用场景: 查询方法接口

    该注解会把方法的返回值缓存下来, 下一次调用方法时, 先查询缓存中是否存在,存在则直接返回,不存在,则查询数据返回,并将数据缓存.

     // 先从缓存中读取,如果没有再调用方法获取数据,然后把数据添加到缓存中
        @Cacheable(value = "user", key = "#id")
        public User select(String id) {
            List<User> users = userMapper.selectAll();
            for (User user : users) {
                if (user.getId().equals(id)) {
                    return user;
                }
            }
            return null;
        }
    

    1.注解属性:

    注解属性 作用
    cacheNames 缓存key前缀名字,设置缓存组件
    key 缓存key后缀
    condition SpringEL表达式,结果为true,缓存数据到redis。结果为false,不缓存数据到redis
    unless SpringEL表达式,结果为false,缓存数据到redis。结果为true,不缓存数据到redis

    2.SpEL上下文数据

    属性名称 描述 示例
    methodName 当前方法名 #root.methodName
    method 当前方法 #root.method.name
    target 当前被调用的对象 #root.target
    targetClass 当前被调用的对象的class #root.targetClass
    args 当前方法参数组成的数组 #root.args[0]
    caches 当前被调用的方法使用的Cache #root.caches[0].name
  3. @Cacheput

    使用场景: 新增或修改方法

    该注解会把方法的返回值Put到缓存中, 供其他查询使用,如果有同一缓存则覆盖.

    // 查询数据库,将返回结果放到缓存
        @CachePut(value = "user", key = "#user.id")
        public User save(User user) {
            userMapper.insert(user);
            return user;
        }
    
  4. @CacheEvict

    使用场景: 删除或修改方法

    该注解会清空指定缓存.

    // 移除对应的缓存
        @CacheEvict(value = "user", key = "#user.id")
        public User update(User user) {
            userMapper.updateByPrimaryKey(user);
            return user;
        }
    
    
  5. @Caching

    使用场景: 同时操作多个缓存

    该注解是一个组合缓存,可以同时添加几个不同的注解,供不同的应用场景使用.如一个接口,可能同时操作多个缓存,且缓存的处理状态都不一样.

    @Caching(
        cacheable = {
            @Cacheable(value = "user",keyGenerator = "xdclassKeyGenerator")
    	},
    	put = {
            @CachePut(value = "user",key = "#id"),
    		@CachePut(value = "user",key = "'stock:'+#id")
    	}
    )
    
  6. @CacheConfig

    该注解用于配置该类中用的一些共用的缓存配置

    @CacheConfig(cacheNames = "cache:prefix")
    

Redis序列化配置类和Cache缓存配置类

@Configuration
public class RedisConfig {

    private static StringRedisSerializer stringRedisSerializer;

    private static Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer;

    static {
        //定义string类型序列化对象
        stringRedisSerializer = new StringRedisSerializer();
        //定义Jackson类型序列化对象
        jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        //解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL
                , JsonTypeInfo.As.WRAPPER_ARRAY);
        jackson2JsonRedisSerializer.setObjectMapper(om);
    }

    @Bean //Redis序列化配置
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        //配置连接工程
        template.setConnectionFactory(factory);
        //redis key序列化方式
        template.setKeySerializer(stringRedisSerializer);
        //redis value序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //hashmap  key序列化
        template.setHashKeySerializer(stringRedisSerializer);
        //hashmap value序列化
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        return template;
    }
    
	//Cache配置
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        // 配置序列化(解决乱码的问题),过期时间600秒
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                //过期时间
                .entryTtl(Duration.ofSeconds(600))
                //缓存key
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer))
                //缓存组件value
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                //value不为空
                .disableCachingNullValues()
                .computePrefixWith(cacheName -> cacheName + ":");

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

Cache的自定义Key策略组件配置

1.配置
@Component("selfKeyGenerate")
public class SelfKeyGenerate implements KeyGenerator {



    public Object generate(Object target, Method method, Object... params) {
        if (params.length == 0) {
            return SimpleKey.EMPTY;
        }
        Object param = params[0];
        // 参数为map自定义key=类名+方法名+map的key-value值
        if (param instanceof Map) {
            StringBuilder builder = new StringBuilder();
//             分隔符
            String sp = ".";

            builder.append(target.getClass().getSimpleName()).append(sp);
            builder.append(method.getName()).append(sp);
            Map<String, Object> map = (Map<String, Object>) param;
            if (map.isEmpty()) {
                return builder.toString();
            }
            for (String key : map.keySet()) {
                builder.append(key).append("-").append(map.get(key)).append(sp);
            }
//            builder.append(IdUtil.randomUUID());
            return builder.toString();
        }
        return new SimpleKey(params);
    }

}
2.使用
@Cacheable(cacheNames = "perCenter",keyGenerator = "selfKeyGenerate")
    public R PersonalCenter(HttpServletRequest request){
        return null;
    }

标签:缓存,springCache,redis,user,key,讲解,return,public
From: https://www.cnblogs.com/kidzxy/p/17170708.html

相关文章

  • Redis哨兵模式
    含义反客为主的自动版,检测主服务器是否宕机,如果宕机后会立即选择一个主服务器下的从服务器再当选主服务器  操作步骤1. 配置哨兵,填写内容自定义的/myredis目录下......
  • Redis薪火相传
    1.1.1.   薪火相传上一个Slave可以是下一个slave的Master,Slave同样可以接收其他slaves的连接和同步请求,那么该slave作为了链条中下一个的master,可以有效减轻master......
  • Redis反客为主
    当一个master宕机后,后面的slave可以立刻升为master,其后面的slave不用做任何修改。用slaveof noone 将从机变为主机。  ......
  • node redis 在服务端使用踩坑
    测试环境正常,生产环境不能正常访问1、测试环境和生产环境不同的是配置的redis不一样,难道是因为redis吗? 类似issue:https://github.com/luin/ioredis/issues?q=++Err......
  • redis有关面试题1
    redis的特点:redis本质上是一个key-value类型的内存数据库,整个数据库系统加载在内存当中操作,定期通过异步操作把数据库数据flash硬盘上进行保存。因为是纯内存操作,redi......
  • Redis中的缓存穿透、雪崩、击穿的原因以及解决方案
    一、概述①缓存穿透:大量请求根本不存在的key(下文详解)②缓存雪崩:redis中大量key集体过期(下文详解)③缓存击穿:redis中一个热点key过期(大量用户访问该热点key,但是热点key......
  • Redis主从复制原理
    1.当从服务器连接上主服务器后,主服务器向从服务器发送进行数据同步消息2.主服务器接到从服务器发送的数据同步的消息,把主服务器数据持久化,复制rdb文件发送给从服务器,从服......
  • redis集群某节点连接数偏高问题处理
    背景接收到监控推送的告警,redis集群某节点连接数偏高,触发告警阈值,但该项目明显没有大流量访问,最近也没有更新程序,虽然对生产暂时不会产生影响,但隐患毕竟是隐患,需排查。#......
  • redis主从复制原理
    小码今天去面试。面试官:给我介绍一下Redis集群,小码:啊,平时开发用的都是单机Redis,没怎么用过集群了。面试官:好的,出门右转不谢。小码内心困惑:在小公司业务量也不大,单机的......
  • Mac 通过 Homebrew 安装 Redis 环境
    前言记录一下安装配置Redis环境的过程和遇到的坑,以防止今后再花大量时间来解决。1.安装Redisbrewinstallredisbrewlinkredis测试一下:#启动Redis服务red......