springboot整合redis--序列化配置文件--如何配置集群模式

299 阅读3分钟

springboot整合Redis

springboot对redis的操作封装到模板类中RedisTemplate和StringRedisTemplate。StringRedisTemplate是Redistemplate的子类,它只能往redis中存放字符串类型。

1.创建springboot工程

image.png

2.依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.13</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>springboot_redis</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_redis</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>

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

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

3.配置信息

#redis的配置信息--单机
spring.redis.host=192.168.94.131
spring.redis.port=6379

4.测试StringRedisTemplate类中的方法

package com.cjj;

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.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import java.util.List;
import java.util.Map;
import java.util.Set;

@SpringBootTest
class SpringbootRedisApplicationTests {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Test
    void contextLoads() {
        //操作key
        final Boolean k2 = redisTemplate.hasKey("k2");//判断某个key是否存在
        System.out.println("判断k2是否存在"+k2);
        final Set<String> keys = redisTemplate.keys("*");//所有的key
        System.out.println("所有的key"+keys);
        final Boolean k1 = redisTemplate.delete("k1");//是否成功删除某个key
        System.out.println("是否成功删除k1"+k1);

        //对于字符串的操作---redisTemplate类中对于每一种数据类型的操作的,单独封装了相应的类
        final ValueOperations<String, String> forValue = redisTemplate.opsForValue();//对字符串的操作类
        forValue.set("k1","cjj");
        final String s = forValue.get("k1");
        System.out.println("获取k1对于value的值"+s);
        forValue.setIfAbsent("k1","aguang");//如果key存在则不会存入
        forValue.setIfAbsent("k2","小美女");
        System.out.println(forValue.get("k1"));
        System.out.println(forValue.get("k2"));

        //对于hash类型的操作
        final HashOperations<String, Object, Object> forHash = redisTemplate.opsForHash();//对hash的操作类
        forHash.put("k3","name","cjj");//存入hash类型的数据
        forHash.put("k3","age","20");
        final Object o = forHash.get("k3", "name");
        System.out.println("name的值是"+o);
        final Map<Object, Object> k3 = forHash.entries("k3");//拿到指定key的所有hash数据
        System.out.println(k3);


        //对于list类型的操作
        final ListOperations<String, String> forList = redisTemplate.opsForList();//对list的操作类
        forList.rightPush("k6", "v6");//在指定key中从右往左放入单个数据
        final String k6 = forList.leftPop("k6");//获取key值,集合左侧的第一个元素
        System.out.println(k6);

        forList.rightPushAll("k7", "v7", "v8", "v9");//在指定key中从右往左放入多个数据
        final String k7 = forList.leftPop("k7");
        System.out.println(k7);

        final List<String> k71 = forList.range("k7", 0, -1);//获取指定key集合中指定下标开始到结束的所有元素
        System.out.println(k71);
//在指定key中删除指定value  count=0删除所有的value相同元素 大于0 从头部开始删除  小于0 从尾部开始删除
        final Long remove = forList.remove("k7", 0, "v7");
        System.out.println(remove);
        
        
        
    //测试使用hash测试存入map集合
//对于hash类型的操作
final HashOperations<String, Object, Object> forHash = redisTemplate.opsForHash();//对hash的操作类
final Student student = new Student("cjj",18);
HashMap<String, Object> map = new HashMap<>();
map.put("name",student.getName());
map.put("age",student.getAge());
forHash.putAll("k3",map);//存入hash类型的数据
final Object o = forHash.get("k3", "name");
System.out.println("name的值是"+o);
final Map<Object, Object> k3 = forHash.entries("k3");//拿到指定key的所有hash数据
System.out.println(k3);


    }

}

5.解决StringRedisTemplate类不允许存储对象

image.png

很显然StringRedisTemplate类中不允许存入对象

我们可以通过使用父类RedisTemplate解决不允许存入对象的问题,但是随着而来的问题就是在存入数据的时候,jdk会进行序列化,造成redis数据库中出现key,value乱码问题。

image.png

image.png

6.解决java存入redis数据乱码问题

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

@Configuration
public class RedisConfig {
    @Bean //把该方法返回的类对象交于spring的IOC容器来管理
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        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);
        template.setConnectionFactory(factory);
        //key序列化方式
        template.setKeySerializer(redisSerializer);
        //value序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //value hashmap序列化  filed value
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.setHashKeySerializer(redisSerializer); //
        return template;
    }
}

7.测试RedisTemplate配置序列化效果

@Autowired
private RedisTemplate redisTemplate;

@Test
void contextLoads() {
     ValueOperations forValue = redisTemplate.opsForValue();
     forValue.set("k1","v1");
    forValue.set("student",new Student("cjj",18));
}

image.png

springboot使用集群模式

#这里为了方便观看,配置的是集群模式,但是在实际开发中,这里只需要配置nginx的地址就可以
spring.redis.cluster.nodes=192.168.94.131:7001,192.168.94.131:7002,192.168.94.131:7003,192.168.94.131:7004,192.168.94.131:7005,192.168.94.131:7006

8.测试springboot集群配置是否生效

@Autowired
private RedisTemplate redisTemplate;

@Test
void contextLoads() {
     ValueOperations forValue = redisTemplate.opsForValue();
     forValue.set("k1","v1");
    forValue.set("student",new Student("cjj",18));
}

image.png