springBoot整合redis(作缓存)
springBoot整合Redis
1,配置Redis配置类
package org.redislearn.configuration;
import java.lang.reflect.Method;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
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.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
@EnableCaching
@Configuration
public class RedisConfiguration extends CachingConfigurerSupport{
    /*
     * key的生成策略(根据目标对象,本例是service实现类,以及其中的方法,参数拼接成一个key)
     * 可以根据业务需求更改策略
     */
    @Override
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            /*
             * 参数1:要操作的目标对象
             * 参数2:要操作的方法
             * 参数3:执行方法时的参数
             */
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sBuilder = new StringBuilder();
                sBuilder.append(target.getClass().getName());
                sBuilder.append(".");
                sBuilder.append(method.getName());    //生成key
                for(Object object:params){
                    sBuilder.append(".");
                    sBuilder.append(object.toString());
                }
                return sBuilder.toString();
            }
        };
    }
    /**
     * redisTemplate相关配置  RedisTemplate操作Redis
     * @param factory
     * @return
     */
    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template  = new RedisTemplate<>();
        //设置工厂
        template.setConnectionFactory(factory);
        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
//(默认使用JDK的序列化方式)
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer =
                new Jackson2JsonRedisSerializer<>(Object.class);
        //创建对象映射
        ObjectMapper mapper = new ObjectMapper();
        //指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
        mapper.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);
        //指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer
//等会抛出异常
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        //
        jackson2JsonRedisSerializer.setObjectMapper(mapper);
        //字符串序列化器
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        //key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        //hash的key也采用String的方式
        template.setHashKeySerializer(stringRedisSerializer);
        //value采用jackson的方式
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //hash的value也采用Jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}
2,配置application.yml配置文件
server:
  port: 8080
mybatis:
  config-location: classpath:mybatis-config.xml
  type-aliases-package: org.xxxx.entity
  mapper-locations:
    - classpath:mapper/*.xml
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC
    username: root
    password: 123456
  redis:
    host: 127.0.0.1
    port: 6379
    password:123456 # 生产环境中需要加上密码,不然数据及其不安全
    jedis:
      pool:
        max-active: 10
        max-idle: 5
        min-idle: 2
        max-wait: -1
3,操作Redis数据库
- RedisTemplate<String,Object> :类似于Mybatis的SqlSession,用来操作数据库的对象
//在需要使用的地方利用spring注入RedisTemplate对象
@Autowired
private RedisTemplate<String,Object> redisTemplate;
4,使用Redis作缓存
- 新建一个实体类
ps:存入redis的实体类数据需要实现序列化接口,不然会报
org.springframework.data.redis.serializer.SerializationException: Cannot deserialize;至于原理,可以看看我看过的这篇文章了解一下
Redis为什么需要序列化https://www.zhihu.com/question/277363840/answer/392945240
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Product implements Serializable {//redis need to serialize
    private int pid;
    private String pname;
    private double price;
    private int store;
    private List<String> images;
    private String detail;
}
- (默认已经写好了mapper,service等接口和相关配置) 
- 在service实现类中的方法加注解 - @Cacheable("xxx") //数据以xxx开头存入缓存
- @CacheEvict(value = {"xxx","xxx"},allEntries = true) //清除缓存中的xxx开头的数据
 - @Service
 public class ProductServiceImpl implements ProductService { @Autowired
 private ProductMapper productMapper; @Cacheable("findAll")
 @Override
 public List<Product> all() {
 return productMapper.all();
 } @Cacheable("findById")
 @Override
 public Product findProductByPid(int pid) {
 return productMapper.findProductByPid(pid);
 } //把跟这个id有关的数据都要删除,这里是"findAll"和"findById"
 @CacheEvict(value = {"findAll","findById"},allEntries = true)
 @Override
 public int deleteProductByPid(int pid) {
 return productMapper.deleteProductByPid(pid);
 }
 }
 - 这里的清除缓存的数据配置有问题,当执行删除方法的时候会将以"findAll","findById"开头的key的其他数据都清除掉,这样之后的查询又是从数据库查,性能再次下降
 - 解决方案: - 写一个工具类,生成对应的key,用来精准删除
 - public class RedisUtil {
 public static String generate(String namespace,Object target, String method, Object... params) {
 StringBuilder sBuilder = new StringBuilder();
 sBuilder.append(namespace);
 sBuilder.append("::"); //自动生成的key会有双冒号
 sBuilder.append(target.getClass().getName());
 sBuilder.append(".");
 sBuilder.append(method); //生成key
 for(Object object:params){
 sBuilder.append(".");
 sBuilder.append(object.toString());
 }
 return sBuilder.toString();
 }
 }
 - 改进service实现类的方法
 - //定义一个需要的命名空间
 private static final String NAMESPACE = "findProductByPid"; //删除指定的key
 @CacheEvict(value = "findAll",allEntries = true)
 @Override
 public int deleteProductByPid(int pid){
 //前缀 this method 参数
 String key = RedisUtil.generate(NAMESPACE,this,"findProductByPid",pid);
 System.out.println(key);
 //操作删除指令
 redisTemplate.delete(key);
 return productMapper.deleteProductByPid(pid);
 }
 - thinking :如果想要保留redis中的findAll的查询,那么可以在封装数据的时候把数据封装成hash,就不用list,通过对象名 的 filed删除这个数据,查询findAll的时候就还是从redis中来数据。但一般情况再从数据库查这一次影响不大,除非,删查非常频繁
 
至此,若有纰漏,望各位不吝赐教
springBoot整合redis(作缓存)的更多相关文章
- SpringBoot整合Redis案例缓存首页数据、缓解数据库压力
		一.硬编码方式 1.场景 由于首页数据变化不是很频繁,而且首页访问量相对较大,所以我们有必要把首页数据缓存到redis中,减少数据库压力和提高访问速度. 2.RedisTemplate Jedis是R ... 
- SpringBoot 整合 Redis缓存
		在我们的日常项目开发过程中缓存是无处不在的,因为它可以极大的提高系统的访问速度,关于缓存的框架也种类繁多,今天主要介绍的是使用现在非常流行的NoSQL数据库(Redis)来实现我们的缓存需求. Spr ... 
- SpringBoot整合Redis、mybatis实战,封装RedisUtils工具类,redis缓存mybatis数据 附源码
		创建SpringBoot项目 在线创建方式 网址:https://start.spring.io/ 然后创建Controller.Mapper.Service包 SpringBoot整合Redis 引 ... 
- Redis-基本概念、java操作redis、springboot整合redis,分布式缓存,分布式session管理等
		NoSQL的引言 Redis数据库相关指令 Redis持久化相关机制 SpringBoot操作Redis Redis分布式缓存实现 Resis中主从复制架构和哨兵机制 Redis集群搭建 Redis实 ... 
- SpringBoot整合Redis、ApachSolr和SpringSession
		SpringBoot整合Redis.ApachSolr和SpringSession 一.简介 SpringBoot自从问世以来,以其方便的配置受到了广大开发者的青睐.它提供了各种starter简化很多 ... 
- SpringBoot整合Redis及Redis工具类撰写
		SpringBoot整合Redis的博客很多,但是很多都不是我想要的结果.因为我只需要整合完成后,可以操作Redis就可以了,并不需要配合缓存相关的注解使用(如@Cacheable). ... 
- springboot整合redis(注解形式)
		springboot整合redis(注解形式) 准备工作 springboot通常整合redis,采用的是RedisTemplate的形式,除了这种形式以外,还有另外一种形式去整合,即采用spring ... 
- springboot整合redis——redisTemplate的使用
		一.概述 相关redis的概述,参见Nosql章节 redisTemplate的介绍,参考:http://blog.csdn.net/ruby_one/article/details/79141940 ... 
- 九、springboot整合redis二之缓冲配置
		1.创建Cache配置类 @Configuration @EnableCaching public class RedisCacheConfig extends CachingConfigurerSu ... 
随机推荐
- AWS 创建redis 集群模式遇到的问题
			问题描述 前几天在aws 平台创建了Redis 集群模式,但是链接集群的时候发现无法连接,返回信息超时. 通过参数组创建redis的时候提示报错:Replication group with spec ... 
- chattr +i  用户也没法随意删除
			root用户也没法用rm随意删除文件? 前言 在你的印象中,是不是root用户就可以为所欲为呢?随便一个rm -rf *,一波骚操作走人?可能没那么容易. 先来个示例,创建一个文本文件test.t ... 
- 实验四 Linux系统C语言开发环境学习
			项目 内容 这个作业属于哪个课程 Linux系统与应用 这个作业的要求在哪里 作业要求链接 学号-姓名 17041428-朱槐健 作业学习目标 1.Linux系统下C语言开发环境搭建 2.学习Linu ... 
- local 对象补充
			昨日回顾 1 @app.before_first_request,再项目启动后接收到的第一个请求,会执行before_first_request,他再@app.before_request之前执行.他 ... 
- 大话微服务(Big Talk in MicroService)
			下面开始分析我的microservice 之旅. what? 是什么 why? 为什么 how? 什么做 1.什么是微服务 microservice 是 SOA(Service-Oriented Ar ... 
- dubbo traceId透传实现日志链路追踪(基于Filter和RpcContext实现)
			一.要解决什么问题: 使用elk的过程中发现如下问题: 1.无法准确定位一个请求经过了哪些服务 2.多个请求线程的日志交替打印,不利于查看按时间顺序查看一个请求的日志. 二.期望效果 能够查看一个请求 ... 
- C# 9.0 新特性之参数非空检查简化
			阅读本文大概需要 1.5 分钟. 参数非空检查是缩写类库很常见的操作,在一个方法中要求参数不能为空,否则抛出相应的异常.比如: public static string HashPassword(st ... 
- Vugen使用技巧
			调整各种选项的超时时间 
- filter()函数过滤序列
			''' Python内建的filter()函数用于过滤序列. 和map()类似,filter()也接收一个函数和一个序列.和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据 ... 
- Jupyter notebook中的Cell and Line Magics
			参考资料: https://www.jianshu.com/p/81ada9234788 https://my.oschina.net/u/2306127/blog/832510 首先,Cell an ... 
