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(作缓存)的更多相关文章

  1. SpringBoot整合Redis案例缓存首页数据、缓解数据库压力

    一.硬编码方式 1.场景 由于首页数据变化不是很频繁,而且首页访问量相对较大,所以我们有必要把首页数据缓存到redis中,减少数据库压力和提高访问速度. 2.RedisTemplate Jedis是R ...

  2. SpringBoot 整合 Redis缓存

    在我们的日常项目开发过程中缓存是无处不在的,因为它可以极大的提高系统的访问速度,关于缓存的框架也种类繁多,今天主要介绍的是使用现在非常流行的NoSQL数据库(Redis)来实现我们的缓存需求. Spr ...

  3. SpringBoot整合Redis、mybatis实战,封装RedisUtils工具类,redis缓存mybatis数据 附源码

    创建SpringBoot项目 在线创建方式 网址:https://start.spring.io/ 然后创建Controller.Mapper.Service包 SpringBoot整合Redis 引 ...

  4. Redis-基本概念、java操作redis、springboot整合redis,分布式缓存,分布式session管理等

    NoSQL的引言 Redis数据库相关指令 Redis持久化相关机制 SpringBoot操作Redis Redis分布式缓存实现 Resis中主从复制架构和哨兵机制 Redis集群搭建 Redis实 ...

  5. SpringBoot整合Redis、ApachSolr和SpringSession

    SpringBoot整合Redis.ApachSolr和SpringSession 一.简介 SpringBoot自从问世以来,以其方便的配置受到了广大开发者的青睐.它提供了各种starter简化很多 ...

  6. SpringBoot整合Redis及Redis工具类撰写

            SpringBoot整合Redis的博客很多,但是很多都不是我想要的结果.因为我只需要整合完成后,可以操作Redis就可以了,并不需要配合缓存相关的注解使用(如@Cacheable). ...

  7. springboot整合redis(注解形式)

    springboot整合redis(注解形式) 准备工作 springboot通常整合redis,采用的是RedisTemplate的形式,除了这种形式以外,还有另外一种形式去整合,即采用spring ...

  8. springboot整合redis——redisTemplate的使用

    一.概述 相关redis的概述,参见Nosql章节 redisTemplate的介绍,参考:http://blog.csdn.net/ruby_one/article/details/79141940 ...

  9. 九、springboot整合redis二之缓冲配置

    1.创建Cache配置类 @Configuration @EnableCaching public class RedisCacheConfig extends CachingConfigurerSu ...

随机推荐

  1. Java基础(十一)

    一.连接到服务器 telnet是一种用于网络编程的非常强大的测试工具,你可以在命令shell中输入telnet来启动它. 二.实现服务器 服务器循环体: 1.通过输入数据流从客户端接收一个命令. 2. ...

  2. OC语言-NSMutableArray为什么要用strong来修饰

    Talk is cheap show you my code!  NSMutableArray属性为什么要用strong来修饰,其实就是一个深复制和浅复制的问题. <pre name=" ...

  3. 基于Azure IoT开发.NET物联网应用系列-全新的Azure IoT架构

    物联网技术已经火了很多年了,业界各大厂商都有各自成熟的解决方案.我们公司主要搞新能源汽车充电,充电桩就是物联网技术的最大应用,车联网.物联网.互联网三网合一.2017年的时候重点研究过Azure Io ...

  4. 1.vue的基础认识

    vue 1.基于MvvM MVC--MVVM,是MVC的改进版      MVVM主要是将视图的状态和行为抽象化,把视图和业务逻辑分开      M:模型--存放状态的容器,是以数据为中心的      ...

  5. Flutter学习笔记(31)--异步更新UI

    如需转载,请注明出处:Flutter学习笔记(31)--异步更新UI 大家都知道,子线程不能操作UI控件,在我们Android的日常开发中,经常会遇到网络请求数据通过线程间通信,将数据发送到UI线程中 ...

  6. (六)MySQL数据、库、表的管理

    目录 数据的管理 库的管理 表的管理 数据的管理 一.数据插入语句 1.语法: INSERT INTO 表名(列名,...) VALUES(值1,...); 2.案例:在beauty表中添加一条信息( ...

  7. [FireDAC][Phys][MSSQL]-310._数据库安装工具_问题需要解决_连载_3

    //先来看看我们碰到的问题,再来求解答SQL脚本执行失败,[FireDAC][Phys][MSSQL]-310. Cannot execute command returning result set ...

  8. Idea创建Scala的Maven项目

    Idea版本(2018.1.5) Scala版本(2.11.0) Java版本(1.8.0_151) 创建Scala的Maven项目 Idea新建项目如图,输入GroupId和ArtifactId之后 ...

  9. Linux下,如何监控某个进程到底向哪个地址发起了网络调用

    Linux下,如何监控某个进程到底向哪个地址发起了网络调用 有时候,有些应用,比如idea,你发起某个操作时,其底层会去请求网络,获取一些数据. 但是不知道,请求了什么地址.举个例子,在idea中,m ...

  10. 小师妹学JVM之:深入理解JIT和编译优化-你看不懂系列

    目录 简介 JIT编译器 Tiered Compilation分层编译 OSR(On-Stack Replacement) Deoptimization 常见的编译优化举例 Inlining内联 Br ...