SpringBoot 整合 Redis

2022-01-17 14:21:05 浏览数 (1)

Java 学习Redis地址是:https://developer.redis.com/develop/java/ 首先 SpringBoot 的 约定优于配置 在整合Redis的时候 就得到了充分的体现

我们几乎不需要手写什么配置,大部分的配置基于SpringBoot配置好的就行。

首先 老规矩,加入 Maven的依赖

代码语言:javascript复制
        <!--springboot中的redis依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

依赖加入好后,刷新一下 Maven,编写我们的配置信息 yml格式

代码语言:javascript复制
spring:
  # 配置redis信息
  redis:
    # redis的ip
    host: 192.168.3.10
    # redis的端口
    port: 6379
    # redis的密码
    password: 123456
    # 指定的redis的数据库
    database: 0

看清楚格式,别弄处什么空格,或者什么的

然后开始写我们的测试用例了。

这里,我直接拿我公司项目来做测试案例代码了

我们核心是 RedisTemplate 所有操作 ,都让他来干。

因为 Redis 有 这5种基本数据结构类型分别为:String(字符串)、List(列表)、Set(集合)、Hash(散列)和 Zset(有序集合)。

我们简单说明这几种类型的特点:

  • String : 类似与Map集合。相同Key 会覆盖原有数据
  • List:
  • Set:
  • Hash:
  • Zset:

实验: Key-Value 存储、读取

代码语言:javascript复制
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * @author : zanglikun
 * @date : 2021/1/29 15:42
 * @Version: 1.0
 * @Desc : Redis的测试使用
 */

@RunWith(SpringRunner.class)  // 这行 不加 就不会由SpringBoot项目管理,就会导致不会走SpringBoot的默认RedisTemplate 的配置,会爆 空指针异常
@SpringBootTest
public class shop1688Test {
    @Autowired
    RedisTemplate redisTemplate;

    @Test
    public void testSet() {
        try {
            redisTemplate.boundValueOps("张三").set("88888");
            System.out.println("存入成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testGet() {
        String s = (String) redisTemplate.boundValueOps("张三").get(); // 没有结果就是 null 有结果就正常输出
        System.out.println("结果是:"   s);
    }
}

RedisTemplate的序列化与反序列化

添加一个 Persion类 用来 下文 操作 JAVA 对象

代码语言:javascript复制
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.io.Serializable;

/**
 * @author : zanglikun
 * @date : 2021/1/29 16:43
 * @Version: 1.0
 * @Desc : 自定义的Player类,用于下文的 正反序列化
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Player implements Serializable {
	private String name;
	private int age;
	private boolean isman;
	private static final long serialVersionUID = 1L;
}

添加一个 Java object 对象 并设置1000秒后 消失

代码语言:javascript复制
    // 往Redis 中 添加一个Java的Player 对象 
    @Test
    public void testSetJavaObject() {
        Player player = new Player();
        player.setAge(21);
        player.setName("臧立昆");
        player.setIsman(true);
        Object o = JSON.toJSON(player);
        Class<?> aClass = o.getClass();
        System.out.println(aClass);
    // 添加一个对象 并设置 数量 1000 单位 为秒 消失的记录
        redisTemplate.opsForValue().set(player.getName(), JSON.toJSON(player),1000, TimeUnit.SECONDS);
        System.out.println("存入成功");
    }

这里 图片 TTL 应该是 1000 但这里-1 所以 我用的是上文的图

取数据 因为直接取数据 不能很好的反序列化并封装在 对象内,所以,只能通过Json的方法转成对象使用。所以我们的解决方案是:添加配置类

代码语言:javascript复制
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.76</version>
        </dependency>

配置一个配置类RedisConfig,以后 使用我们的配置过序列化的 RedisTemplate 模板类 操作了 模板类如下

代码语言:javascript复制
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
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;
/**
 * @Author: 臧立昆
 * @Email: 740969606@qq.com
 * @Date: 2020/8/1
 * @Time: 18:53
 */
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
    
    // 自己定义了一个 RedisTemplate
    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        // 我们为了自己开发方便,一般直接使用 <String, Object>
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(factory);
        // Json序列化配置
        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);
        // String 的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

    //自定义cacheManager缓存管理器
    @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);

        //配置序列化(解决乱码的问题)

        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ZERO)
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();

        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }

}

实验:反序列化查询一个 JAVA对象(前提是存储好了)

代码语言:javascript复制
    @Test
    public void testGetJavaObject() throws ClassNotFoundException {
        JSONObject obj = (JSONObject)redisTemplate.opsForValue().get("臧立昆");
        Player player = JSON.toJavaObject(obj, Player.class);
        System.out.println(player);
    }

搞定。

特殊说明: 解决问题的光鲜,藏着磕Bug的痛苦。 万物皆入轮回,谁也躲不掉! 以上文章,均是我实际操作,写出来的笔记资料,不会出现全文盗用别人文章!烦请各位,请勿直接盗用!

0 人点赞