SpringBoot 整合 Redis

SpringBoot操作数据:spring-data jpa jdbc mongodb redis !

SpringData也是和SpringBoot齐名的项目!

说明:在SpringBoot2.X之后,原来使用的jedis被替换成了lettuce

jedis:采用的直连,多个线程操作的话,是不安全的,如果想要避免不安全的,使用jedis pool连接池!更像BIO模式

lettuce:采用netty,实例可以在多个线程中进行共享,不存在线程不安全的情况!可以减少线程数据了,更像NIO模式
  • 提供了对不同 Redis 客户端的整合 (Lettuce和Jedis)
  • 提供了 RedisTemplate 统一 API 来操作 Redis
  • 支持 Redis 的发布订阅模型
  • 支持 Redis 哨兵和 Redis 集群
  • 支持基于 Lettuce 的响应式编程
  • 支持基于 JDK、JSON、字符串、Spring 对象的数据序列化及反序列化
  • 支持基于 Redis 的 JDKCollection 实现

SpringDataRedis 中提供了 RedisTemplate 工具类,其中封装了各种对 Redis 的操作。并且将不同数据类型的 API 封装到了不同的类型中:

API 返回值类型 说明
redisTemplate.opsForValue() ValueOperations 操作 String 类型数据
redisTemplate.opsForHash() HashOperations 操作 Hash 类型数据
redisTemplate.opsForList() ListOperations 操作 List 类型数据
redisTemplate.opsForSet() SetOperations 操作 Set 类型数据
redisTemplate.opsForZSet() ZSetOperations 操作 SortedSet 类型数据

整合测试

1、导入依赖

<dependencies>
  <!--Redis 依赖-->
  <dependency>
  <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-redis</artifactId>
  </dependency>

  <!--连接池依赖-->
  <dependency>
  <groupId>org.apache.commons</groupId>
 <artifactId>commons-pool2</artifactId>
 <version>2.11.1</version>
  </dependency>
</dependencies>

2、配置连接

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    database: 0
    password: 123456
    # 连接超时时间
    timeout: 1800000
    lettuce:
      pool:
        # 连接池最大连接数
        max-active: 20
        # 最大阻塞等待时间(负数表示没有限制)
        max-wait: 1
        # 连接池中最大空闲连接
        max-idle: 5
        # 连接池中最小空闲连接
        min-idle: 0

3、测试

@SpringBootTest
class SpringbootRedisApplicationTests {

  @Autowired
  private RedisTemplate<String,String> redisTemplate;

  @Test
  void contextLoads() {
  //redisTemplate 操作不同的数据类型
  //opsForValue   //操作字符串 类似String
 //opsForList    //操作List 类似List
 //opsForSet //opsForHash //opsForZSet //opsForGeo
 //除了基本的操作,我们常用的方法都可以直接通过redisTemplate操作,比如事务,和基本的CRUD
  redisTemplate.opsForValue().set("myKey","myValue");
  System.out.println(redisTemplate.opsForValue().get("myKey"));
  }

}

源码分析:

@Bean
@ConditionalOnMissingBean(name = "redisTemplate")//我们可以自定义一个redisTemplate来替换这个默认的!
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)throws UnknownHostException {
    //默认的RedisTemplate 没有过多的设置,redis对象都是需要序列化的!
    //两个泛型都是Object类型,Object的类型,我们使用需要强制转换<String,Object>
    RedisTemplate<Object, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
}

@Bean
@ConditionalOnMissingBean//由于String 是redis中最常用的类型,所以单独出来一个bean!
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)throws UnknownHostException {
    StringRedisTemplate template = new StringRedisTemplate();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
}

SpringBoot 整合 Redis

SpringBoot 整合 Redis

RedisTemplate 可以接收任意 Object 作为值写入 Redis,只不过写入前会把 Object 序列化位字节字节形式,默认是采用 JDK 序列化

缺点

  • 可读性差
  • 占用内存大

配置 redisTemplate 序列化方式

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        // 创建 RedisTemplate
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        // 设置连接工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 设置序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        // key 和 hashKey 采用 string 序列化
        redisTemplate.setKeySerializer(RedisSerializer.string());
        redisTemplate.setHashKeySerializer(RedisSerializer.string());
        // value 和 hashValue 采用 JSON 序列化
        redisTemplate.setValueSerializer(jsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jsonRedisSerializer);
        return redisTemplate;
    }
}
@SpringBootTest
public class RedisTest {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Test
    void test() {
        Student student = new Student(1, "HuDu", 18);
        redisTemplate.opsForValue().set("student", student);
        System.out.println(redisTemplate.opsForValue().get("student"));
    }
}

存入 Redis 之后,结果为

127.0.0.1:6379> get student
"{\"@class\":\"com.hudu.domain.entry.Student\",\"id\":1,\"name\":\"HuDu\",\"age\":18}"

尽管 JSON 的序列化方式可以满足我们的需求,但依然存在一些问题,为了在反序列化时,知道对象的类型,JSON 序列化器会将类的 class 类型写入 json 结果中,存入 redis,会带来额外的内存开销。

为了节省内存空间,我们并不会使用JSON序列化器来处理value,而是统一使用 String 序列化器 ,要求只能存储 String 类型的 key 和 value。当需要存储 Java 对象时,手动完成对象的序列化和反序列化。

官方提供了StringRedisTemplate,通过手动将对象转化为 json 字符串存入 redis 中。

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
247
粉丝
17
喜欢
213
收藏
58
排名:732
访问:9674
私信
所有博文
社区赞助商