springboot与缓存(整合redis)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 Tair(兼容Redis),内存型 2GB
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
简介: 缓存就是数据交换的缓冲区(称作:Cache),他把一些外存上的数据保存在内存上,为什么保存在内存上,我们运行的所有程序里面的变量都是存放在内存中的,所以如果想将值放入内存上,可以通过变量的方式存储。在JAVA中一些缓存一般都是通过Map集合来实现的。

一、什么是缓存

缓存就是数据交换的缓冲区(称作:Cache),他把一些外存上的数据保存在内存上,为什么保存在内存上,我们运行的所有程序里面的变量都是存放在内存中的,所以如果想将值放入内存上,可以通过变量的方式存储。在JAVA中一些缓存一般都是通过Map集合来实现的。

缓存在不同的场景下,作用是不一样的具体举例说明:
✔  操作系统磁盘缓存 ——> 减少磁盘机械操作。
✔  数据库缓存——>减少文件系统IO。
✔  应用程序缓存——>减少对数据库的查询。
✔  Web服务器缓存——>减少应用服务器请求。
✔  客户端浏览器缓存——>减少对网站的访问。

具体关于缓存的详细介绍以及缓存的面试问题可以参考这篇博客

三、几个重要概念&缓存注解

1、Cache:

缓存接口,定义缓存操作。实现有:RedisCache、EhCacheCache、ConcurrentMapCache等

2、CacheManager

缓存管理器,管理各种缓存(Cache)组件

3、@Cacheable

主要针对方法配置,能够根据方法的请求参数对其结果进行缓存

(后面会细说该注解)

4、@CacheEvict

清空缓存

5、@CachePut

保证方法被调用,又希望结果被缓存。

6、@EnableCaching

开启基于注解的缓存

7、keyGenerator

缓存数据时key生成策略

8、serialize

缓存数据时value序列化策略

9、@Cacheable/@CachePut/@CacheEvict 主要的参数

网络异常,图片无法展示
|

网络异常,图片无法展示
|

四、springboot整合redis实现缓存

1、引入依赖

在pom.xml中引入spring-boot-starter-data-redis依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2、配置redis连接地址

在application.yml或者application.properties中配置redis连接地址

这里还需要配置一下数据库的地址,方便测试使用

application.properties配置

spring.datasource.url=jdbc:mysql://MySQL的主机地址:3306/数据库名
spring.datasource.username=root
spring.datasource.password=密码
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# 启用mybatis的命名策略(即驼峰命名法)
mybatis.configuration.map-underscore-to-camel-case=true
logging.level.com.atguigu.cache.mapper=debug
debug=true
spring.redis.host=redis主机地址

application.yml配置:

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://MySQL的主机地址:3306/数据库名
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource #配置Druid数据源
    #   数据源其他配置
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
    #   配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
  redis:
    host: redis主机地址
#mybatis:
#  config-location: classpath:mybatis/mybatis-config.xml
# 开启驼峰命名
mybatis:
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    com.canghe.springboot.mapper: debug
debug: true
#  mapper-locations: classpath:mybatis/mapper/*.xml

3、在虚拟机或者云服务器上安装redis

可以直接通过docker安装redis,并配置端口

4、使用RestTemplate操作redis

@Autowired
    StringRedisTemplate stringRedisTemplate;//操作k-v都是字符串
    @Autowired
    RedisTemplate redisTemplate;//操作k-v对象的

Redis常见的五大数据类型

String(字符串) 、list(列表)、set(集合)、hash(散列)、Zset(有序集合)

  1. redisTemplate.opsForValue();//操作字符串
  2. redisTemplate.opsForHash();//操作hash
  3. redisTemplate.opsForList();//操作list
  4. redisTemplate.opsForSet();//操作set
  5. redisTemplate.opsForZSet();//操作有序set

测试代码:

@Test
    public void test01() {
//        stringRedisTemplate.opsForValue().append("key","helloword");
//        String msg = stringRedisTemplate.opsForValue().get("key");
//        System.out.println("msg:"+msg);
        stringRedisTemplate.opsForList().leftPush("firstList","1");
        stringRedisTemplate.opsForList().leftPush("firstList","2");
    }

五、@Cacheable注解

1、运行流程

1、方法运行之前,先去查询Cache(缓存组件),按照cacheNames指定的名字获取;(CacheManager先获取相应的缓存),第一次获取缓存如果没有Cache组件会自动创建。
2、去Cache中查找缓存的内容,使用一个key,默认就是方法的参数; key是按照某种策略生成的;默认是使用keyGenerator生成的,默认使用SimpleKeyGenerator生成key; SimpleKeyGenerator生成key的默认策略;
如果没有参数;key=new SimpleKey();
如果有一个参数:key=参数的值
如果有多个参数:key=new SimpleKey(params);

3、没有查到缓存就调用目标方法;

4、将目标方法返回的结果,放进缓存中

@Cacheable标注的方法执行之前先来检查缓存中有没有这个数据,默认按照参数的值作为key去查询缓存,**
如果没有就运行方法并将结果放入缓存;以后再来调用就可以直接使用缓存中的数据;**

2、核心

1)、使用CacheManager【ConcurrentMapCacheManager】按照名字得到Cache【ConcurrentMapCache】组件
2)、key使用keyGenerator生成的,默认是SimpleKeyGenerator

3、几个属性

  • cacheNames/value:指定缓存组件的名字;将方法的返回结果放在哪个缓存中,是数组的方式,可以指定多个缓存;
  • key:缓存数据使用的key;可以用它来指定。默认是使用方法参数的值  1-方法的返回值, 编写SpEL; #i d;参数id的值   #a0  #p0  #root.args[0]    getEmp[2]
  • keyGenerator:key的生成器;可以自己指定key的生成器的组件id,key/keyGenerator:二选一使用;
  • cacheManager:指定缓存管理器;或者cacheResolver指定获取解析器
  • condition:指定符合条件的情况下才缓存; condition = "#a0>1":第一个参数的值》1的时候才进行缓存
  • unless:否定缓存;当unless指定的条件为true,方法的返回值就不会被缓存;可以获取到结果进行判断
unless = "#result == null"
     *              unless = "#a0==2":如果第一个参数的值是2,结果不缓存;


  • sync:是否使用异步模式

@Cacheable例子:

@Cacheable(value = {"emp"}/*,keyGenerator = "myKeyGenerator",condition = "#a0>1",unless = "#a0==2"*/)
    public Employee getEmp(Integer id){
        System.out.println("查询"+id+"号员工");
        Employee emp = employeeMapper.getEmpById(id);
        return emp;
    }

六、@CachePut

1、启用场景

既调用方法,又更新缓存数据;同步更新缓存,修改了数据库的某个数据,同时更新缓存;

2、运行时机

  • 先调用目标方法
  • 将目标方法的结果缓存起来

3、测试步骤

1、查询1号员工;查到的结果会放在缓存中;
key:1  value:lastName:张三
2、以后查询还是之前的结果
3、更新1号员工;【lastName:zhangsan;gender:0】
将方法的返回值也放进缓存了;
key:传入的employee对象  值:返回的employee对象;
4、查询1号员工?
应该是更新后的员工;
key = "#employee.id":使用传入的参数的员工id;
key = "#result.id":使用返回后的id
@Cacheable的key是不能用#result
为什么是没更新前的?【1号员工没有在缓存中更新】

@CachePut(/*value = "emp",*/key = "#result.id")
    public Employee updateEmp(Employee employee){
        System.out.println("updateEmp:"+employee);
        employeeMapper.updateEmp(employee);
        return employee;
    }

七、@CacheEvict

缓存清除

/**
     * @CacheEvict:缓存清除
     *  key:指定要清除的数据
     *  allEntries = true:指定清除这个缓存中所有的数据
     *  beforeInvocation = false:缓存的清除是否在方法之前执行
     *      默认代表缓存清除操作是在方法执行之后执行;如果出现异常缓存就不会清除
     *
     *  beforeInvocation = true:
     *      代表清除缓存操作是在方法运行之前执行,无论方法是否出现异常,缓存都清除
     *
     *
     */
    @CacheEvict(value="emp",beforeInvocation = true/*key = "#id",*/)
    public void deleteEmp(Integer id){
        System.out.println("deleteEmp:"+id);
        //employeeMapper.deleteEmpById(id);
        int i = 10/0;
    }

八、@Caching

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
7天前
|
缓存 NoSQL 关系型数据库
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
本文详解缓存雪崩、缓存穿透、缓存并发及缓存预热等问题,提供高可用解决方案,帮助你在大厂面试和实际工作中应对这些常见并发场景。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
|
8天前
|
存储 缓存 NoSQL
【赵渝强老师】基于Redis的旁路缓存架构
本文介绍了引入缓存后的系统架构,通过缓存可以提升访问性能、降低网络拥堵、减轻服务负载和增强可扩展性。文中提供了相关图片和视频讲解,并讨论了数据库读写分离、分库分表等方法来减轻数据库压力。同时,文章也指出了缓存可能带来的复杂度增加、成本提高和数据一致性问题。
【赵渝强老师】基于Redis的旁路缓存架构
|
7天前
|
NoSQL Java API
springboot项目Redis统计在线用户
通过本文的介绍,您可以在Spring Boot项目中使用Redis实现在线用户统计。通过合理配置Redis和实现用户登录、注销及统计逻辑,您可以高效地管理在线用户。希望本文的详细解释和代码示例能帮助您在实际项目中成功应用这一技术。
15 3
|
9天前
|
消息中间件 NoSQL Java
Spring Boot整合Redis
通过Spring Boot整合Redis,可以显著提升应用的性能和响应速度。在本文中,我们详细介绍了如何配置和使用Redis,包括基本的CRUD操作和具有过期时间的值设置方法。希望本文能帮助你在实际项目中高效地整合和使用Redis。
25 1
|
15天前
|
缓存 NoSQL 中间件
redis高并发缓存中间件总结!
本文档详细介绍了高并发缓存中间件Redis的原理、高级操作及其在电商架构中的应用。通过阿里云的角度,分析了Redis与架构的关系,并展示了无Redis和使用Redis缓存的架构图。文档还涵盖了Redis的基本特性、应用场景、安装部署步骤、配置文件详解、启动和关闭方法、systemctl管理脚本的生成以及日志警告处理等内容。适合初学者和有一定经验的技术人员参考学习。
105 7
|
15天前
|
JavaScript NoSQL Java
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
30 0
|
存储 缓存 NoSQL
Spring Boot2.5 实战 MongoDB 与高并发 Redis 缓存|学习笔记
快速学习 Spring Boot2.5 实战 MongoDB 与高并发 Redis 缓存
Spring Boot2.5 实战 MongoDB 与高并发 Redis 缓存|学习笔记
|
缓存 NoSQL 安全
6.0Spring Boot 2.0实战 Redis 分布式缓存6.0|学习笔记
快速学习6.0Spring Boot 2.0实战 Redis 分布式缓存6.0。
327 0
6.0Spring Boot 2.0实战 Redis 分布式缓存6.0|学习笔记
|
缓存 NoSQL Redis
首页数据显示-添加 redis 缓存(3)| 学习笔记
快速学习 首页数据显示-添加 redis 缓存(3)
150 0
首页数据显示-添加 redis 缓存(3)| 学习笔记
|
缓存 NoSQL Java
首页数据显示-添加 redis 缓存(1) | 学习笔记
快速学习 首页数据显示-添加 redis 缓存(1)
235 0
首页数据显示-添加 redis 缓存(1) | 学习笔记

热门文章

最新文章