Springboot高级(一)缓存

news2025/2/26 9:48:49

一、缓存结构

在这里插入图片描述

二、注解

在这里插入图片描述

三、体验缓存

1、开启缓存 @EnableCaching

@SpringBootApplication
@EnableCaching
public class SpringbootCacheApplication {

2、标志注解

(1)Cacheable

	@Cacheable(value = "emp", condition ="#id==2", 
				unless = "#result == null")
    public Employee getEmpById(Integer id) {
        Employee emp = employeeMapper.getEmpById(id);
        return emp;
    }
注意:Springboot2.X版本以上必须添加value属性
属性作用
value指定缓存的名字
cacheNames指定缓存的名字
key缓存数据时的key(默认使用参数,SpEL表达式)
keyGeneratorkey的生成器
cacheManager缓存管理器
condition指定符合条件才缓存
unless除非
sync异步

在这里插入图片描述

运行流程:
@Cacheable:

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

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

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

指定自己的keyGenerator


 @Cacheable(value = "emp", keyGenerator = "myKeyGenerator")

@Configuration
public class KeyGeneratorConfig {

    @Bean("myKeyGenerator")
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... objects) {
                return method.getName() + '[' + Arrays.asList(objects).toString() + ']';
            }
        };
    }
}

(2)@CachePut

既调用方法,又更新缓存,实现同步缓存。
先调用方法,再将结果缓存起来。

    @CachePut(value = "emp", key = "#entity.id")
    public Employee edit(Employee entity){
        employeeMapper.updateEmp(entity);
        return entity;
    }

测试步骤:

  1. 先查询1号员工,放入缓存中

  2. 更新1号员工

  3. 再次查询

    注:@CachePut和@Cacheable的key值必须一样,例如:查询的#id和更新的#entity.id都代表1
    

(3)@CacheEvict

@CacheEvict(value = "emp", key = "#id")
    public void remove(Integer id){
        System.err.println("删除的id" + id);
        employeeMapper.deleteEmpById(id);
    }
allEntries = true   // 删除所以缓存
beforeInvocation = true   //true在方法之前清除缓存,false在方法之后清除缓存

(4)@Caching 复杂注解

	@Caching(
            cacheable = { @Cacheable(value = "emp", key = "#lastName")},
            put = { 
            		@CachePut(value = "emp", key = "#result.id"),
                    @CachePut(value = "emp", key = "#result.email")
                  }
    )
    public Employee getByLastName(String lastName) {
       return employeeMapper.getByLastName(lastName);
    }

查询到数据放入到了put缓存中,key通过id和email查询缓存

(5)@CacheConfig

类上公共配置

@CacheConfig(cacheNames = "emp")
@Service
public class EmployeeService {

四、整合Redis

1、引入

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

2、配置

spring.redis.port=6379
spring.redis.host=127.0.0.1

3、整合

(1)对Redis五种基本类型的操作

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    StringRedisTemplate stringRedisTemplate;
    
    @Test
    void test01(){
        //操作String类型
        stringRedisTemplate.opsForValue();
        //操作List类型
        stringRedisTemplate.opsForList();
        //操作set类型
        stringRedisTemplate.opsForSet();
        //操作hash类型
        stringRedisTemplate.opsForHash();
        //操作Zset类型
        stringRedisTemplate.opsForZSet();

        redisTemplate.opsForValue();
    }
	//向redis中缓存msg
    @Test
    void test01(){
        stringRedisTemplate.opsForValue().append("msg", "第一个消息");
        
        stringRedisTemplate.opsForList().leftPush("nameList", "张三");
        stringRedisTemplate.opsForList().leftPush("nameList", "李四");
        stringRedisTemplate.opsForList().leftPush("nameList", "allen");
    }
	//从redis中获取缓存msg
    @Test
    void test02(){
        String msg = stringRedisTemplate.opsForValue().get("msg");
        System.err.println(msg);

        List<String> myList = stringRedisTemplate.opsForList().range("nameList", 0, -1);
        for (String str : myList) {
            System.err.println(str);
        }
    }

(2)缓存实体


	public class Employee implements Serializable {
			....
	}

    @Test
    void  test03(){
        Employee entity = new Employee();
        entity.setId(1);
        entity.setName("小明");
        entity.setPassword("123456");

        redisTemplate.opsForValue().set("emp.01", entity);
    }
注意: 如此缓存,序列化会出问题(转义)

在这里插入图片描述

进行优化- -JSON格式化

@Configuration
public class MyRedisTemplate {
    @Bean
    public RedisTemplate<Object, Employee> empRedisTemplate
    					(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Employee> template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);

        Jackson2JsonRedisSerializer<Employee> serializer = 
        	new Jackson2JsonRedisSerializer<Employee>(Employee.class);
        template.setDefaultSerializer(serializer);
        return template;
    }
}

    @Test
    void  test03(){
        Employee entity = new Employee();
        entity.setId(2);
        entity.setName("小红");
        entity.setPassword("123456");
        empRedisTemplate.opsForValue().set("emp.02", entity);
    }

在这里插入图片描述

4、原理

缓存注解还是原先的,只是改变了CahceManager

1、引入redis的starter,容器中保存的是RedisCacheManager;
2、RedisCacheManager帮我们创建 RedisCache 来作为缓存组件;RedisCache通过操作redis缓存数据
3、默认保存数据 k-v 都是Object;利用序列化保存,使用jdk的序列化机制
4、自定义CacheManager
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/427338.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【李老师云计算】实验一:Hadoop伪分布式集群部署与Eclipse访问Hadoop进行单词计数统计

索引前言实验内容1. 安装虚拟机1.1 安装与激活1.2 ★解决使用虚拟机蓝屏(绿屏)2. 安装CentOS2.1 下载CentOS2.2 VMware新建虚拟机2.3 安装CentOS(包括GUI、主机名)2.4 ★解决已经创建虚拟机改主机名3. VMWare 网络配置3.0 使用VI编辑器和VMware3.0.1 使用VI编辑器3.0.2 使用VMw…

SQL Server 数据操控,视图和索引

文章目录前言1.在student表中插入一行新记录&#xff0c;学号为&#xff0c;姓名为胡明月&#xff0c;性别为男&#xff0c;年龄为&#xff0c;系部为CS2.在student表中插入一条新记录&#xff0c;学号为&#xff0c;姓名为李红&#xff0c;性别为女3.将胡明月的年龄修改为194.…

R语言实践——ggplot2+ggrepel绘制散点+优化注释文本位置

简介 书接adjustText实践——调整matplotlib散点图标签&#xff0c;避免重复 上文中&#xff0c;matplotlibadjustText对于我的实例来说并没有起到很好的效果。所以&#xff0c;博主决定在R中利用gglot2ggrepel绘制&#xff0c;期待效果。 操作过程 博主不常使用R&#xff…

尚融宝14-集成redis缓存

目录 一、简介 1、场景 2、RedisTemplate 二、引入Redis 1、项目中集成Redis 2、添加Redis连接配置 3、启动Redis服务 三、测试RedisTemplate 1、存值测试 2、Redis配置文件 3、取值测试 四、将数据字典存入redis 一、简介 1、场景 由于数据字典的变化不是很频繁&#xff0c;而…

Unity 热更新技术 | (四) Lua语言基本语法及关键知识介绍

🎬 博客主页:https://xiaoy.blog.csdn.net 🎥 本文由 呆呆敲代码的小Y 原创,首发于 CSDN🙉 🎄 学习专栏推荐:Unity系统学习专栏 🌲 游戏制作专栏推荐:游戏制作 🌲Unity实战100例专栏推荐:Unity 实战100例 教程 🏅 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬…

python ——批量读取相同格式文件(多个文件夹/单个文件夹)---nc文件为例

在处理多个相同格式的文件时&#xff0c;python中的许多模块可以为我们提供很多遍历。 比如&#xff0c;我们想读取一个文件夹下多个相同格式的文件时 可以使用os模块&#xff0c; import os以下有几个常见用法&#xff1a; 1、os.path.abspath(path) #返回绝对路径 2、os.pat…

【周末闲谈】畅想AR,AR领域迎来新风口

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️周末闲谈】 周末闲谈 ✨第一周 二进制VS三进制 ✨第二周 文心一言&#xff0c;模仿还是超越&#xff1f; 文章目录周末闲谈前言AR?&#x1f914;&#x1f914;&#x1f914;AR的发展&#x1f463;&…

Matplotlib数据可视化

Matplotlib是⼀个Python 2D&#xff0c;3D绘图库&#xff0c;它以多种硬拷⻉格式和跨平台的交互式环境⽣成出版物质量的图形。 MatplotlibMatplotlib中文网、Matplotlib官方中文文档。https://www.matplotlib.org.cn/ 1.模块导⼊ import matplotlib.pyplot as plt #使⽤py…

分布式事务详解

&#x1f3c6;今日学习目标&#xff1a; &#x1f340;分布式事务详解 ✅创作者&#xff1a;林在闪闪发光 ⏰预计时间&#xff1a;30分钟 &#x1f389;个人主页&#xff1a;林在闪闪发光的个人主页 &#x1f341;林在闪闪发光的个人社区&#xff0c;欢迎你的加入: 林在闪闪发光…

Web 攻防之业务安全:密码找回安全案例总结.

Web 攻防之业务安全&#xff1a;密码找回安全案例总结 业务安全是指保护业务系统免受安全威胁的措施或手段。广义的业务安全应包括业务运行的软硬件平台&#xff08;操作系统、数据库&#xff0c;中间件等&#xff09;、业务系统自身&#xff08;软件或设备&#xff09;、业务所…

微软New Bing初体验:AI时代的搜索引擎(内含体验方法)

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…

AI未来十年新范式,生成式人工智能的挑战与机遇

目录0 写在前面1 什么是生成式模型&#xff1f;2 生成式模型的挑战3 自主智能新架构4 持续学习与表征解耦4.1 学习范式4.2 学习架构5 生成式AI与元宇宙6 智慧文档&#xff1a;赋能数字化转型7 结语0 写在前面 2023年3月18日&#xff0c;由中国图象图形学学会&#xff08;CSIG&…

【李老师云计算】HBase+Zookeeper部署及Maven访问

索引前言1. Zookeeper1.1 主机下载Zookeeper安装包1.2 主机解压Zookeeper1.3 ★解决解压后文件缺失1.4 主机配置Zookeeper文件1.4.1 配置zoo_sample.cfg文件1.4.2 配置/data/myid文件1.5 主机传输Zookeeper文件到从机1.6 从机修改Zookeeper文件1.6.1 修改zoo.cfg文件1.6.2 修改…

生成器设计模式(Builder Design Pattern)[论点:概念、图示、示例、框架中的应用、场景]

文章目录概念相关图示代码示例框架中的应用场景多个生成器&#xff08;Concrete Builder&#xff09;&#xff1a;单个生成器概念 生成器设计模式&#xff08;Builder Design Pattern&#xff09;是一种创建型设计模式&#xff0c;用于处理具有多个属性和复杂构造过程的对象。生…

【Linux学习】信号——信号保存 | 信号处理 | 不可重入函数,volatile,SIGCHLD信号

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《Linux学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 信号的产生以及详细讲解了&#xff0c;有兴趣的小伙伴可以去看看&#xff0c;传送门。接下来介绍…

快速尝鲜Oracle 23c免费开发者版,惊喜多多

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

hive数据仓库--Hive介绍

1 什么是HiveHive是基于Hadoop的⼀个数据仓库⼯具&#xff0c;⽤来进⾏数据提取、转化、加载&#xff0c;这是⼀种可以存储、查询和分析存储在Hadoop中的⼤规模数据的机制。Hive数据仓库⼯具能将结构化的数据⽂件映射为⼀张数据库表&#xff0c;并提供类SQL的查询功能&#xff…

spring(七):事务操作

spring&#xff08;七&#xff09;&#xff1a;事务操作前言一、什么是事务二、事务四个特性&#xff08;ACID&#xff09;三、事务操作&#xff08;搭建事务操作环境&#xff09;四、事务操作&#xff08;Spring 事务管理介绍&#xff09;五、事务操作&#xff08;注解声明式事…

SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解分布式情况下如何添加分布式锁 【续篇】

文章目录前言1、分布式情况下如何加锁2、具体实现过程3、测试3.1 一个服务按照多个端口同时启动3.2 使用jmeter进行压测前言 上一篇实现了单体应用下如何上锁,这一篇主要说明如何在分布式场景下上锁 上一篇地址:加锁 1、分布式情况下如何加锁 需要注意的点是: 在上锁和释放…

C/C++每日一练(20230412)

目录 1. 二维数组找最值 &#x1f31f;&#x1f31f; 2. 排序 &#x1f31f; 3. 二叉树展开为链表 &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 二维…