SpringBoot 整合Redis 实战篇

一、解决数据乱码问题🍉

在上篇文章中我们整合了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;
    }
    
}

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 好的,下面是使用Spring Boot集成Redis实战的步骤: 1. 添加Redis依赖 在pom.xml文件中添加Redis依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` 2. 配置Redis连接信息 在application.properties文件中添加Redis连接信息: ```properties spring.redis.host=127.0.0.1 spring.redis.port=6379 spring.redis.password=yourpassword spring.redis.database=0 ``` 3. 创建RedisTemplate 在Java代码中创建RedisTemplate对象,用于对Redis进行操作: ```java @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); // 设置key序列化方式 redisTemplate.setKeySerializer(new StringRedisSerializer()); // 设置value序列化方式 redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); // 设置hash key序列化方式 redisTemplate.setHashKeySerializer(new StringRedisSerializer()); // 设置hash value序列化方式 redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); return redisTemplate; } } ``` 4. 使用RedisTemplate操作Redis 通过RedisTemplate对象可以对Redis进行操作,例如: ```java @Autowired private RedisTemplate<String, Object> redisTemplate; // 存储字符串 redisTemplate.opsForValue().set("name", "ChatGPT"); // 获取字符串 String name = (String) redisTemplate.opsForValue().get("name"); // 存储对象 User user = new User(); user.setId(1); user.setName("ChatGPT"); redisTemplate.opsForValue().set("user", user); // 获取对象 User user = (User) redisTemplate.opsForValue().get("user"); ``` 5. 使用Redis缓存 可以使用Spring Cache注解将方法结果缓存到Redis中,例如: ```java @Service @CacheConfig(cacheNames = "user") public class UserService { @Autowired private UserDao userDao; @Cacheable(key = "#id") public User getUserById(int id) { return userDao.getUserById(id); } @CachePut(key = "#user.id") public User updateUser(User user) { userDao.updateUser(user); return user; } @CacheEvict(key = "#id") public void deleteUserById(int id) { userDao.deleteUserById(id); } } ``` 上面的代码使用了@Cacheable注解将getUserById方法的结果缓存到名为"user"的缓存中,使用@CachePut注解将updateUser方法的结果更新到缓存中,使用@CacheEvict注解从缓存中删除deleteUserById方法的结果。 以上就是使用Spring Boot集成Redis实战的步骤,希望能够帮助到你。 ### 回答2: Spring Boot是一个非常强大的Java应用程序开发框架,它支持快速开发和部署应用程序,并且提供了大量的插件和集成库,可以帮助开发者快速构建高效的应用程序。其中,集成Redis是非常常见的需求,因为Redis提供了快速和可扩展的缓存和持久化解决方案。 Spring BootRedis集成非常简单,可以通过在应用程序中添加适当的依赖和配置来完成。首先,需要在maven或gradle中添加spring-boot-starter-data-redis的依赖,以便在应用程序中使用Spring Data Redis模块。 接下来,需要在application.properties文件中添加Redis的配置信息。其中,包括Redis服务器的主机名、端口号、密码以及连接池的一些基本配置信息等等。例如: spring.redis.host=localhost spring.redis.port=6379 spring.redis.password=123456 除了以上的配置信息,还需要在项目中创建一个RedisTemplate对象来连接到Redis服务器,同时在需要使用Redis功能的类中注入RedisTemplate对象,以便进行各种Redis操作。 最后,可以利用Spring Boot提供的注解来实现Redis的缓存或消息队列功能。例如,使用@Cacheable注解为方法提供缓存支持,使用@RedisListener注解为方法提供消息订阅支持等等。 总而言之,Spring Boot集成Redis非常简单且易于维护,在项目中可以经常使用Redis作为缓存或消息队列,从而提高应用程序的响应速度和可靠性。 ### 回答3: Spring Boot是一个轻量级的Java框架,能够快速构建和部署Java应用程序。Redis是一种流行的内存数据结构存储,常用于缓存和消息传递。将Spring Boot集成Redis是非常重要的,因为它可以提高应用程序的性能和扩展性,同时也可以减少数据库负载。以下是Spring Boot集成Redis的实践: 1. 引入redis依赖 在pom.xml文件中加入redistemplate和jedis依赖。 ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.1.0</version> </dependency> ``` 2. 配置Redis 在application.properties文件中添加Redis配置。这里涉及到Redis服务器、连接池大小、超时时间等参数的设置。 ``` spring.redis.host=localhost spring.redis.port=6379 spring.redis.timeout=30000 spring.redis.pool.max-idle=8 spring.redis.pool.min-idle=0 spring.redis.pool.max-active=8 spring.redis.password=123456 ``` 3. 编写Redis工具类 在src/main/java包下,创建RedisUtil.java文件,实现Redis的连接管理和基本操作(如set、get、delete等)。 ``` @Component public class RedisUtil { @Autowired private StringRedisTemplate stringRedisTemplate; public void set(String key, String value) { stringRedisTemplate.opsForValue().set(key, value); } public String get(String key) { return stringRedisTemplate.opsForValue().get(key); } public void delete(String key) { stringRedisTemplate.delete(key); } } ``` 4. 在应用程序中使用Redis 在需要使用Redis的类中,注入RedisUtil并调用对应的方法即可。 ``` @RestController @RequestMapping("/redis") public class RedisController { @Autowired private RedisUtil redisUtil; @GetMapping("/set") public String setRedis(String key, String value) { redisUtil.set(key, value); return "Set redis success."; } @GetMapping("/get") public String getRedis(String key) { return redisUtil.get(key); } @GetMapping("/delete") public String deleteRedis(String key) { redisUtil.delete(key); return "Delete redis success."; } } ``` 上述代码中,RedisController中的setRedis、getRedis、deleteRedis分别对应RedisUtil中的set、get、delete操作。这里使用@RestController注解,表示这是一个REST风格的控制器,可以对外提供接口服务。 5. 运行应用程序 将应用程序打成jar包并运行,可以使用Postman等工具测试接口。测试方法如下: - 调用/set接口,传入key和value,将数据写入Redis中。 - 调用/get接口,传入key,获取Redis中保存的value。 - 调用/delete接口,传入key,删除Redis中保存的value。 以上是Spring Boot集成Redis实战过程。通过配置Redis依赖,设置Redis连接参数,编写Redis操作工具类和控制器,即可在Spring Boot应用程序中轻松使用RedisSpring Boot集成Redis可以提高应用程序的性能和扩展性,同时也可以减少数据库负载,是值得推荐的实践。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值