SpringBoot 整合Redis 实战篇

news2024/11/25 3:03:15

一、解决数据乱码问题🍉

在上篇文章中我们整合了redis,当我们存入一个对象时会发现redis中的数据存在乱码问题,这是jdk编码的问题
在这里插入图片描述

springboot整合redis时提供了两个模板工具类,StringRedisTemplate和RedisTemplate.

1.使用RedisTemplate时需要为key和value设置序列化🥝

在这里插入图片描述

package com.lzq.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
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.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String ,Object> template = new RedisTemplate<>();
        StringRedisSerializer redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setConnectionFactory(factory);
        //key序列化方式
        template.setKeySerializer(redisSerializer);
        //value序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //value hashmap序列化  filed value
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.setKeySerializer(redisSerializer);
        return template;
    }
}

2.测试🥝

在这里插入图片描述
在这里插入图片描述

当我们配置好序列化文件之后就不需要转换类型或者在进行序列化操作,直接可以向redis中填入对象类型也不存在编码问题,方便了我们的编码操作

package com.lzq;


import com.lzq.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@SpringBootTest
class RedisSpringbootApplicationTests {
    @Autowired
    private RedisTemplate redisTemplate;
    @Test
    void contextLoads() {
        //对key进行序列化
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //对value进行序列化
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());

        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set("k1","v1");//存储的都是字符串类型,看到存放的数据乱码---对key进行序列化时采用的是默认的JDK序列化方式。要对应的类必须实现序列接口
        System.out.println(valueOperations.get("k1"));

        valueOperations.set("k31",new User("张三",28));
        Object user = valueOperations.get("k3");
        System.out.println(user);
    }

    @Test
    public void test03(){
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set("k22","v22");
        valueOperations.set("k23",new User("阿娇",18));
    }

}

二、 springboot使用redis集群模式🍉

1.更改配置文件🥝

在这里插入图片描述

2.打开redis集群模式🥝

在这里插入图片描述
在这里插入图片描述

3.测试连接🥝

在这里插入图片描述

  @Test
    public void test04(){
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set("kkk","vvv");
        Object kkk = valueOperations.get("kkk");
        System.out.println(kkk);
    }

三、使用redis作为缓存🍉

在这里插入图片描述
Redis因为其自身高性能的数据读取能力,因此会经常被应用到缓存的场景中

1.连接数据库配置数据源🥝

在这里插入图片描述

#redis?????--??
#spring.redis.host=192.168.179.129
#spring.redis.port=6379
# nginx??redis??
spring.redis.cluster.nodes=192.168.179.129:7001,192.168.179.129:7002,192.168.179.129:7003,192.168.179.129:7004,192.168.179.129:7005,192.168.179.129:7006


spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db2?serverTimezone=Asia/Shanghai&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456

在这里插入图片描述

2.实现单表操作的缓存🥝

在这里插入图片描述

package com.lzq.service;

import com.lzq.dao.StudentDao;
import com.lzq.pojo.Student;
import javafx.scene.DepthTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class StudentService {
    @Autowired
    private StudentDao studentDao;
    @Autowired
    private RedisTemplate redisTemplate;

    //查询操作
    public Student findByid(Integer id){
        //创建redis操作字符串对象
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //查看缓存是否存在该数据  有缓存则不需要对数据库进行操作
        Object o = valueOperations.get("student:" + id);
        //判断产看是否为空  并且为需要的student对象
        if (o!=null && o instanceof Student){
            return (Student) o;
        }
        //查看数据库
        Student student = studentDao.selectById(id);
        if (student!=null){
            //把查出的数据放到缓存中  key  value  过期时间 过期单位
            valueOperations.set("student:"+id,student,30, TimeUnit.HOURS);
        }
        return student;

    }

    //修改操作
    public Student update(Student student){
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //先删除数据库中的缓存
        redisTemplate.delete("student:"+student.getSid());
        //再修改数据库中的数据
        studentDao.updateById(student);
        return student;
    }
    //添加操作
    public Student insert(Student student){
        studentDao.insert(student);
        return student;
    }
    //删除操作
    public int delete(int id){
        //先删除缓存数据
        redisTemplate.delete("student:"+id);
        //再对数据库进行操作
        int i = studentDao.deleteById(id);
        return i;
    }


}

思考: AOP—可以把一些非核心业务代码抽象----抽取为一个切面类@Aspect. 在结合一些注解完成相应的切面功能。 Spring框也能想到,Spring在3.0以后提高了缓存注解。可以帮你把功能抽取。

3.使用注解简化缓存操作🥝

1)配置缓存配置🍓

在这里插入图片描述

package com.lzq.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String ,Object> template = new RedisTemplate<>();
        StringRedisSerializer redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setConnectionFactory(factory);
        //key序列化方式
        template.setKeySerializer(redisSerializer);
        //value序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //value hashmap序列化  filed value
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.setKeySerializer(redisSerializer);
        return template;
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        //解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 配置序列化(解决乱码的问题),过期时间600秒
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(600)) //缓存过期10分钟 ---- 业务需求。
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))//设置key的序列化方式
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) //设置value的序列化
                .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }
}

2)开启缓存注解🍓

在这里插入图片描述

@EnableCaching//开启缓存注解驱动  也可以再配置类中添加

3)使用缓存注解🍓

在这里插入图片描述

package com.lzq.service;

import com.lzq.dao.StudentDao;
import com.lzq.pojo.Student;
import javafx.scene.DepthTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class StudentService {
    @Autowired
    private StudentDao studentDao;
    @Autowired
    private RedisTemplate redisTemplate;

    //查询操作
    public Student findByid(Integer id){
        //创建redis操作字符串对象
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //查看缓存是否存在该数据  有缓存则不需要对数据库进行操作
        Object o = valueOperations.get("student:" + id);
        //判断产看是否为空  并且为需要的student对象
        if (o!=null && o instanceof Student){
            return (Student) o;
        }
        //查看数据库
        Student student = studentDao.selectById(id);
        if (student!=null){
            //把查出的数据放到缓存中  key  value  过期时间 过期单位
            valueOperations.set("student:"+id,student,30, TimeUnit.HOURS);
        }
        return student;

    }

    //修改操作
    public Student update(Student student){
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //先删除数据库中的缓存
        redisTemplate.delete("student:"+student.getSid());
        //再修改数据库中的数据
        studentDao.updateById(student);
        return student;
    }
    //添加操作
    public Student insert(Student student){
        studentDao.insert(student);
        return student;
    }
    //删除操作
    public int delete(int id){
        //先删除缓存数据
        redisTemplate.delete("student:"+id);
        //再对数据库进行操作
        int i = studentDao.deleteById(id);
        return i;
    }

    //查询操作

    //使用于查询的缓存注解: 缓存的名称叫做: cacheNames::key
    //先从缓存中找名字叫:cacheNames::key 如果存在,则方法不执行。如果不存在会执行方法,并把改方法的返回值作为缓存的值.
    //必须开启缓存注解驱动
    @Cacheable(cacheNames = "dept",key="#id")
    public Student findByid2(Integer id){
        //创建redis操作字符串对象
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //查看缓存是否存在该数据  有缓存则不需要对数据库进行操作
        Object o = valueOperations.get("student:" + id);
        //判断产看是否为空  并且为需要的student对象
        if (o!=null && o instanceof Student){
            return (Student) o;
        }
        //查看数据库
        Student student = studentDao.selectById(id);
        if (student!=null){
            //把查出的数据放到缓存中  key  value  过期时间 过期单位
            valueOperations.set("student:"+id,student,30, TimeUnit.HOURS);
        }
        return student;

    }

    //修改操作

    //先执行方法体,并把方法的返回结果作为缓存的值。修改缓存的值。
    @CachePut(cacheNames = "dept",key="#dept.id")
    public Student update2(Student student){
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //先删除数据库中的缓存
        redisTemplate.delete("student:"+student.getSid());
        //再修改数据库中的数据
        studentDao.updateById(student);
        return student;
    }
    //添加操作
    public Student insert2(Student student){
        studentDao.insert(student);
        return student;
    }

    //删除操作

    //删除缓存再执行方法体
    @CacheEvict(cacheNames = "dept",key = "#id")
    public int delete2(int id){
        //先删除缓存数据
        redisTemplate.delete("student:"+id);
        //再对数据库进行操作
        int i = studentDao.deleteById(id);
        return i;
    }
    
}

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

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

相关文章

Vue指令--v-if、v-show、v-for

目录 v-if和v-show指令的展示如下&#xff1a; v-for指令的展示如下&#xff1a; v-if和v-show指令的展示如下&#xff1a; v-if指令具有两个配套的指令v-else-if和v-else进行条件判断来决定是否渲染展示某元素 具体代码展示如下&#xff1a;&#xff08;代码中的注释值得一…

音视频入门知识学习

音视频入门知识学习 视频相关视频压缩空间冗余时间冗余视觉冗余信息熵冗余知识冗余 I帧 P帧 B帧 压缩思路I帧P帧B帧 H.264VCLNALNAL&#xff08;片&#xff08;宏块&#xff09;&#xff09; 音频概念采样和采样频率采样位数声道码率声音与音频数字音频相关特点时域冗余频域冗余…

Redis高可用——哨兵模式

Redis——哨兵模式 一、Redis 哨兵模式1.哨兵模式的作用2.故障转移机制3.主节点的选举 二、搭建Redis 哨兵模式1.修改 Redis 哨兵模式的配置文件&#xff08;所有节点操作&#xff09;2.启动哨兵模式3.查看哨兵信息4.故障模拟5.验证结果 一、Redis 哨兵模式 主从切换技术的方法…

【网络原理之一】应用层协议、传输层协议UDP和TCP,TCP的三次握手和四次挥手以及TCP的可靠和效率机制

应用层协议XML协议JSONHTTP 传输层协议UDP协议UDP的特点UDP协议格式 TCP协议TCP的特点TCP协议格式TCP的安全和效率机制确认应答(可靠机制)超时重传(可靠机制)连接管理(可靠机制)三次握手(连接过程)四次挥手(断开的过程)状态的转化 滑动窗口(效率机制)流量控制(可靠机制)拥塞控制…

遥感云大数据在灾害、水体与湿地领域典型案例及GPT模型

详情点击链接&#xff1a;遥感云大数据在灾害、水体与湿地领域典型案例实践及GPT模型 第一&#xff1a;基础 一&#xff1a;平台及基础开发平台 GEE平台及典型应用案例&#xff1b; GEE开发环境及常用数据资源&#xff1b; ChatGPT、文心一言等GPT模型 JavaScript基础&am…

企业如何认识数字化及数字化战略

随着信息和通信技术的发展&#xff0c;数字技术在各个领域广泛应用并深入影响生活、工作和社会的时代。在这个时代里&#xff0c;数字技术不仅改变了我们与世界互动的方式&#xff0c;还催生了全新的商业模式、服务和机会。 数字化时代的关键特征包括&#xff1a; 数字技术的…

Flutter开发微信小程序实战:构建一个简单的天气预报小程序

微信小程序是一种快速、高效的开发方式&#xff0c;Flutter则是一款强大的跨平台开发框架。结合二者&#xff0c;可以轻松地开发出功能丰富、用户体验良好的微信小程序。 这里将介绍如何使用Flutter开发一个简单的天气预报小程序&#xff0c;并提供相应的代码示例。 1. 准备工…

2023年最新Java八股文面试题,面试应该是够用了(吊打面试官)

前言大家先看一下互联网大厂各职级薪资对应表&#xff08;技术线&#xff09;&#xff0c;看看你想到哪个级别去&#xff01; 每个技术人都有个大厂梦&#xff0c;我觉得这很正常&#xff0c;并不是饭后的谈资而是每个技术人的追求。像阿里、腾讯、美团、字节跳动、京东等等的技…

小型企业如何进行高效的文档数据管理?

关键词&#xff1a;知识文档管理系统、群晖NAS、数据安全 我国小型企业数量占全国总数的98%以上&#xff0c;但企业在文档数据管理方面存在诸多问题。比如&#xff1a;文档管理混乱、文档共享不便利、传统的FTP传输文件文档安全难以保障等。 但由于市面上的文档管理产品价格高昂…

思科Cisco C9200交换机端口调配

前言 最近DNAC和交换机等网络设备之间的同步出现问题&#xff0c;在思科的BUG库里找到了相关信息&#xff0c;DNAC2.2.3.6版本的BUG&#xff0c;导致交换机端口的调配无法成功部署推送。但是因为业务的需求&#xff0c;需要对交换机进行端口调配。其和华为/华三的逻辑一致&…

让你不再好奇音频转换格式软件免费有哪些

小美&#xff1a;你好&#xff0c;最近我需要将一些音频文件转换成其他格式&#xff0c;但是不知道常用的音频转换工具有哪些&#xff0c;你有什么建议吗&#xff1f; 李明&#xff1a;当然&#xff0c;有很多音频转换工具可以选择。建议你关注下这篇文章&#xff0c;我将通过…

Bluez HCI Commands

在 lib/Hci.h 头文件中定义了很的我 HCI Commands&#xff0c;这些命令是分组的&#xff0c;每个组下面又提供了具体的命令&#xff0c;如&#xff1a; 其中 OGF 为 OpCode Group Flag&#xff0c;表明命令级别 OCF 为 OpCode Command Flag&#xff0c;表明要执行的命令 Hci…

泰迪智能科技基于产业技能生态链学生学徒制的双创工作室--促进学生高质量就业

据悉&#xff0c;6月28日&#xff0c;广东省人力资源和社会保障厅在广东岭南现代技师学院举行广东省“产教评”技能生态链建设对接活动。该活动以“新培养、新就业、新动能”为主题&#xff0c;总结推广“产教评”技能人才培养新模式&#xff0c;推行“岗位培养”学徒就业新形式…

【无标题】用Javascript编写魔方程序(详解)2023-7-4

第一步&#xff0c;先初始化魔方&#xff0c;如上图&#xff0c;可以很直观的看到魔方的6个面。直接贴代码 <!doctype html> <html><head><meta charset"utf-8"><meta name"viewport" content"widthdevice-width, initia…

微信小程序之Image那些事

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、使用场景二、使用方式1.动态读取image大小2.动态设置style3.动态赋值 总结 前言 小程序中 Image使用频率是非常高的 不同场景下 Image使用的属性也不一样 …

中级保育员专业知识卫生管理考试题库及答案

本题库是根据最新考试大纲要求&#xff0c;结合近年来考试真题的重难点进行汇编整理组成的全真模拟试题&#xff0c;考生们可以进行专项训练&#xff0c;查漏补缺巩固知识点。本题库对热点考题和重难点题目都进行了仔细的整理和编辑&#xff0c;相信考生在经过了针对性的刷题练…

【Redisson】Redisson--话题(订阅分发)

Redisson系列文章&#xff1a; 【Redisson】Redisson–基础入门【Redisson】Redisson–布隆(Bloom Filter)过滤器【Redisson】Redisson–分布式锁的使用&#xff08;推荐使用&#xff09;【分布式锁】Redisson分布式锁底层原理【Redisson】Redisson–限流器、【Redisson】Redi…

你知道ai绘画以图生图软件怎么使用吗?

小美&#xff1a;嗨&#xff0c;张华&#xff0c;你听说过这个令人难以置信的新技术“以图生图ai绘画”吗&#xff1f;它简直让人惊叹&#xff01; 张华&#xff1a;没有&#xff0c;我还没有听说过。什么是以图生图ai绘画&#xff1f; 小美&#xff1a;你看这些美丽的照片&a…

Apikit 自学日记:创建自动化测试项目

在API 自动化测试中&#xff0c;所有的测试用例都是以项目维度来进行管理&#xff0c;一个自动化测试项目可以从多个API文档项目中引用API信息来创建API测试用例。 点击左侧菜单栏&#xff0c;进入 API自动化测试 项目列表页&#xff0c;点击添加按钮&#xff1a; 在弹窗中输入…

六大排序——(插入、希尔、选择、交换、归并、计数)

目录 一、插入排序 二、希尔排序 三、选择排序 1&#xff09;直接选择排序&#xff1a; 2&#xff09;堆排序 四、交换排序 1&#xff09;冒泡排序 2&#xff09;快速排序 1、Hoare版 2、挖坑法 3、前后指针 快排优化 快速排序非递归来实现 快排总结 五、归并排…