关于SpringBoot如何整合Redis

1. Redis的Java客户端简介

在Redis官网中提供了各种语言的客户端,地址:https://redis.io/docs/connect/clients/

其中Java客户端也包含很多:

标记为*的就是推荐使用的java客户端,包括:

  • Jedis和Lettuce:这两个主要是提供了Redis命令对应的API,方便我们操作Redis,而SpringDataRedis又对这两种做了抽象和封装,因此我们后期会直接以SpringDataRedis来学习。

  • Redisson:是在Redis基础上实现了分布式的可伸缩的java数据结构,例如Map、Queue等,而且支持跨进程的同步机制:Lock、Semaphore等待,比较适合用来实现特殊的功能需求。

2. Jedis客户端与pringDataRedis客户端的区别

        Jedis是一个Java的Redis客户端,而Spring Data Redis是Spring提供的用于与Redis进行集成的库。它们之间有以下几个区别:

  • 定位与使用方式:
    • Jedis: Jedis客户端提供了直接的、原生的Redis操作API,是对Redis命令的直接封装。开发者可以直接使用Jedis提供的方法来操作Redis,需要自己处理连接管理、连接池和序列化等问题。
    • Spring Data Redis: Spring Data Redis是在Jedis的基础上进行的进一步封装,提供了更高级的特性和更方便的使用方式。它是Spring框架的一部分,通过提供一组简化的API,减少了开发者对底层Redis连接和操作的关注。
  • 功能与特性:

    • Jedis: Jedis提供了对Redis命令的完整覆盖,支持执行各种Redis命令和事务操作。但是,Jedis对于一些高级特性比如连接池、集群、管道等的支持相对较弱,需要开发者自己实现。
    • Spring Data Redis: Spring Data Redis在Jedis的基础上提供了更多的高级特性,如对象序列化、缓存、分布式锁、响应式编程等。它抽象了连接管理和序列化等细节,提供了更简单、更易于使用的API。
  • 扩展性:

    • Jedis: Jedis是一个独立的Redis客户端,可以根据特定业务需求进行定制和扩展。开发者可以自行封装Jedis的使用方式,或者基于其底层实现自定义功能。
    • Spring Data Redis: Spring Data Redis基于Spring框架,充分利用了Spring的扩展机制。它提供了很多扩展点,可以通过自定义实现接口来定制和扩展更多的功能。

        总的来说,Jedis是一个原生且灵活的Redis客户端,适用于需要直接对Redis进行精细控制的场景。而Spring Data Redis是在Jedis基础上进行封装的高级Redis集成库,提供了更简化的API和更高级的特性,适用于开发者希望使用Spring框架进行集成和更高层次抽象的场景。

3. Jedis客户端

        Jedis的官网地址: GitHub - redis/jedis: Redis Java client

3.1 引入Maven依赖

        <!-- 单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.2</version>
        </dependency>
        <!--jedis-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.7.0</version>
        </dependency>

3.2 建立连接池

        Jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,因此我们推荐大家使用Jedis连接池代替Jedis的直连方式。

package com.zsh.redistest.demos.common.config;
import redis.clients.jedis.*;

/**
 * Jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,因此我们推荐大家使用Jedis连接池代替Jedis的直连方式。
 * @Author ZhaoShuHao
 * @create 2023/11/19
 */
public class JedisConnectionFactory {

    private static JedisPool jedisPool;

    static {
        // 配置连接池
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        //设置连接池中允许的最大活跃(正在使用)连接数。在这里,它被设置为8,表示连接池中最多允许有8个活跃连接。
        poolConfig.setMaxTotal(8);
        //设置连接池中允许的最大空闲连接数。在这里,它被设置为8,表示连接池中最多允许有8个空闲连接。
        poolConfig.setMaxIdle(8);
        //设置连接池中维持的最小空闲连接数。在这里,它被设置为0,表示连接池中最少要维持0个空闲连接。
        poolConfig.setMinIdle(0);
        //设置当连接池中没有可用连接时,应用程序请求连接的最大等待时间,超过该时间将抛出异常。在这里,它被设置为1000毫秒(1秒),表示当没有可用连接时,应用程序最多等待1秒。
        poolConfig.setMaxWaitMillis(1000);
        // 创建连接池对象,参数:连接池配置、服务端ip、服务端端口、超时时间、密码
        jedisPool = new JedisPool(poolConfig, "127.0.0.1", 6379, 1000);
    }

    public static Jedis getJedis(){
        return jedisPool.getResource();
    }
}

3.3 编写测试类

package com.zsh.redistest.demos.controller;

import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;

import java.util.Map;

import static com.zsh.redistest.demos.common.config.JedisConnectionFactory.getJedis;

/**
 * @Author ZhaoShuHao
 * @create 2023/11/19
 */
public class JedisTest {
    @Test
    void testString() {
        Jedis jedis = getJedis();
        // 存入数据
        String result = jedis.set("name", "南风");
        System.out.println("result = " + result);
        // 获取数据
        String name = jedis.get("name");
        System.out.println("name = " + name);
    }

    @Test
    void testHash() {
        Jedis jedis = getJedis();
        // 插入hash数据
        jedis.hset("user:1", "name", "南风");
        jedis.hset("user:1", "age", "23");

        // 获取
        Map<String, String> map = jedis.hgetAll("user:1");
        System.out.println(map);
    }
}

4.SpringDataRedis客户端

        SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis,官网地址:Spring Data Redis

  • 提供了对不同Redis客户端的整合(Lettuce和Jedis)

  • 提供了RedisTemplate统一API来操作Redis

  • 支持Redis的发布订阅模型

  • 支持Redis哨兵和Redis集群

  • 支持基于Lettuce的响应式编程

  • 支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化

  • 支持基于Redis的JDKCollection实现

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

// redisTemplate  #操作不同的数据类型,api和我们的指令是一样的 
// opsForValue  #操作字符串 类似String 
// opsForList  #操作List 类似List 
// opsForSet  #操作set
// opsForHash  #操作hash
// opsForZSet  #操作zset
// opsForGeo   #操作geo
// opsForHyperLogLog  #操作HyperLogLog
// 除了基本的操作,我们常用的方法都可以直接通过redisTemplate操作,比如事务,和基本的 CRUD 
// 获取redis的连接对象 
// RedisConnection connection = redisTemplate.getConnectionFactory().getConnection(); 
// connection.flushDb(); 
// connection.flushAll();

4.1 引入Maven依赖

 <!--redis依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!--common-pool-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <!--Jackson依赖-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</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>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>
        <!-- 单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.2</version>
        </dependency>

4.2 配置redis

server:
  port: 8080
  redis:
    host: localhost
    port: 6379
    lettuce:
      pool:
        max-active: 8 #连接池中允许的最大活动(正在使用)的连接数
        max-idle: 8   #连接池中允许的最大空闲连接数。
        min-idle: 0   #连接池中维持的最小空闲连接数。
        max-wait: 100ms #当连接池中没有可用连接时,最大等待时间,超过该时间将抛出异常

4.3 编写测试类

这里模拟了一下token过期的业务场景

package com.zsh.redistest.demos.common.constant;

/**
 * 常量
 * @Author ZhaoShuHao
 * @create 2023/11/19
 */
public class WechatConstant {
    //键
    public static String REDISTOKENKEY = "wechat:token";
    //过期时间(单位秒),一般企业微信的过期时间是2小时(7200秒)
    public static int REDISTOKENTIMEOUT = 7200;
}
package com.zsh.redistest.demos.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
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.StringRedisTemplate;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

import static com.zsh.redistest.demos.common.constant.WechatConstant.*;

/**
 * @Author ZhaoShuHao
 * @create 2023/11/19
 */
@SpringBootTest
class RedisStringTests {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    // JSON序列化工具
    private static final ObjectMapper mapper = new ObjectMapper();

    //保存token,并设置过期时间
    public String saveToken(){
        //假设获取到了企业微信的token
        String token = "isujagfuisdgfijsdhfojhjsdaoffsafsa";
        // 写入数据
        stringRedisTemplate.opsForValue().set(REDISTOKENKEY, token);
        //设置过期时间
        stringRedisTemplate.expire(REDISTOKENKEY, REDISTOKENTIMEOUT, TimeUnit.SECONDS);
        // 获取数据
        String result = stringRedisTemplate.opsForValue().get(REDISTOKENKEY);
        if(StringUtils.isEmpty(result)){
            System.out.println("token保存失败");
        }else {
            System.out.println("token保存成功");
        }
        return result;
    }
    //获取token是否过期
    public String getToken(){
        String token = null;
        // 获取数据
        Long expire = stringRedisTemplate.opsForValue().getOperations().getExpire(REDISTOKENKEY);
        System.out.println(expire);
        //getExpire()方法的返回值单位为秒,-2表示键不存在或已过期,-1表示键存在但未设置过期时间。
        if(expire== -2){
            System.out.println("token已过期");
        }else {
            System.out.println("token未过期");
            token = stringRedisTemplate.opsForValue().get(REDISTOKENKEY);
        }
        return token;
    }
    //获取token,先判断是否过期,若过期就保存,并拿到token.若未过期就直接获取token
    @Test
    public void changeToken(){
        String token = getToken();
        if(StringUtils.isEmpty(token)){
            saveToken();
        }else {
            System.out.println("获取到token:"+token);
        }
    }
}

4.4 StringRedisTemplate与RedisTemplate的区别

  StringRedisTemplateRedisTemplate是Spring Data Redis库提供的两种常用的Redis操作模板类,它们在功能和使用方式上有一些区别。

  • 数据存储方式:

    • StringRedisTemplate用于与Redis服务器交互存储字符串类型的数据,例如简单的键值对。
    • RedisTemplate用于与Redis服务器交互存储任意类型的数据,包括字符串、对象等。
  • 序列化和反序列化:

    • StringRedisTemplate默认使用的是Redis的字符串序列化器,将对象转换为字符串存储在Redis中。
    • RedisTemplate提供了对多种序列化器的支持,默认使用JDK的序列化器,也可以配置为其他的序列化方式,如JSON、Jackson等。
  • 方法调用:

    • StringRedisTemplate提供了更简洁方便的API,专门针对字符串类型数据的操作。例如,opsForValue()方法返回的是ValueOperations<String, String>对象,提供了字符串类型数据的操作方法。
    • RedisTemplate提供了更通用、灵活的API,可以处理更多种类的数据。例如,通过opsForValue()方法,可以返回ValueOperations<String, Object>对象,进行字符串和对象类型数据的操作。

        选择使用 StringRedisTemplate还是RedisTemplate取决于您存储的数据类型以及应用程序的需求。如果您只需要存储简单的键值对且值为字符串类型,可以选择使用StringRedisTemplate。如果您需要存储多种类型的数据,或者对数据的序列化方式有特殊需求,可以选择使用RedisTemplate

        在性能方面,StringRedisTemplate和RedisTemplate的区别主要体现在两个方面:序列化和操作命令。

  • 序列化:

    • StringRedisTemplate:StringRedisTemplate默认使用的是String的序列化策略,将数据以字符串的形式存储在Redis中。这种序列化方式对于存储简单的字符串数据非常高效,不需要进行额外的序列化和反序列化处理。
    • RedisTemplate:RedisTemplate默认使用的是JDK的序列化策略,将数据以二进制的形式存储在Redis中。虽然JDK序列化支持处理复杂的数据类型,但它在性能上相对较低,并且存储的数据在Redis中是以二进制形式展示的。
  • 操作命令:

    • StringRedisTemplate:StringRedisTemplate提供了更多针对字符串数据的特定命令操作,例如set、get、incr等,这些命令直接对应于Redis的命令,使用更为简单和直观。
    • RedisTemplate:RedisTemplate提供了更加通用的操作方法,适用于操作更复杂的数据结构(例如Hash、List、Set等)。但对于简单字符串操作,需要开发者进行一些额外的封装和转换。

        综上,在性能方面,StringRedisTemplate由于使用了较为简洁的字符串序列化策略,可以在存储简单文本数据时有较好的性能表现。而RedisTemplate由于支持更多复杂数据类型和自定义序列化策略,适用于处理数据结构较为复杂的场景。当需要在性能和灵活性之间做出选择时,可以根据具体场景来选择使用StringRedisTemplate或RedisTemplate。

5. 关于Redis的图形化桌面客户端

GitHub上的大神编写了Redis的图形化桌面客户端,地址:GitHub - RedisInsight/RedisDesktopManager

不过该仓库提供的是RedisDesktopManager的源码,并未提供windows安装包。

在下面这个仓库可以找到安装包:Releases · lework/RedisDesktopManager-Windows · GitHub

下载安装后,双击运行RDM,点击连接到redis服务器,输入相关信息,即可连接redis,进行图形化操作。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值