ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Jedis使用操作

2022-01-25 23:05:52  阅读:170  来源: 互联网

标签:redis Redis 命令 Client Jedis 使用 操作 pool


一:简介

  在浏览本篇文章时务必要会Redis的基本命令,因为在一些主流语言中使用一些其它Redis客户端时都是基于基本命令来操作的;比如在java项目中使用连接Redis客户端有Jedis、Redisson、Jredis、JDBC-Redis;不过官方推荐我们使用Jedis和Redisson;本文章中我会使用Jedis和SpringDataRedis来操作远程的Redis服务端。

  Jedis封装了Redis的一些命令操作,它是Redis的Java客户端,和我们在Redis自带的客户端输入的命令一样,Jedis也提供了连接池管理,可以不用每次关闭连接Redis而消耗时间。

  SpringDataRedis是Spring大家族的一部分,提供了在Spring应用中通过简单的配置访问Redis服务,对Redis底层开发包(Jedis, JRedis, and RJC)进行了高度封装,RedisTemplate提供了redis各种操作、异常处理及序列化,支持发布订阅等,不过在高版本中SpringDataRedis底层则不在使用Jedis。(后续介绍SpringDataRedis)

1:务必看看

  注:本篇文章的命令都在我之前的 【Redis命令】 一文中都详细说明了,我也是参照那篇文章转换为Java程序来实现;遇到不会的命令只须参照【Redis命令】一文 Ctrl+F 直接搜索那个命令即可;而且使用Jedis只要找到你需要的方法,方法参数和官方命令顺序都是一样的,而且简单易上手,主要是知道某个命令干啥的就行;还有就是我的文章只是参考,具体的大家可以参考官方文档!

二:Jedis继承关系分析

1:Jedis类

  Jedis提供了Redis客户端的连接和命令查询,从Jedis继承关系中发现它实现很多的命令接口,每个接口都定义了不同的操作形式,这符合面向对象开发原则中的接口隔离原则和单一职责原则。下面的接口声明了相关的redis命令操作,每个接口都负责对一部分的命令进行方法声明

Jedis父类BinaryJedis所依赖的接口:
    BasicCommands:
        提供基础的查询命令,如ping,quit,flushdb
    BinaryJedisCommands:
        提供了针对redis数据结构的CURD等操作,其中参数(K-V)必须以byte数组形式提供
    MultiKeyBinaryCommands:
        提供了针对redis数据结构的CURD等批量操作,其中参数(K-V)必须以byte数组形式提供
    AdvancedBinaryJedisCommands:
        提供高级操作redis的命令,如config相关,slowlog,client等命令,其中参数(K-V)必须以byte数组形式提供
    BinaryScriptingCommands:
        提供Lua脚本运行命令,命令必须以byte数组形式提供。
Jedis所依赖的接口:
    JedisCommands:
        提供了针对redis数据结构的CURD等操作,其中参数(K-V)必须以String形式提供
    MultiKeyCommands:
        提供了针对redis数据结构的CURD等批量操作,其中参数(K-V)必须以String数组形式提供
    AdvancedJedisCommands:
        提供高级操作redis的命令,如config相关,slowlog,client等命令,其中参数(K-V)必须以String形式提供
    ScriptingCommands:
        提供Lua脚本运行命令,命令必须以String形式提供。
    BasicCommands:
        提供如ping,quit,flushDb运维类命令
    ClusterCommands:
        提供集群状态查看,集群操作的命令
    SentinelCommands:
        提供哨兵操作命令
    ModuleCommands:
        提供redis模块加载和卸载命令

2:Client类

  除了方法接口声明之外,Jedis还提供了客户端Client,使用该类仍然可以连接Redis服务端并进行相关的命令操作。Client本身只是提供相关的命令方法,这些方法声明定义在Commands接口,连接操作则定义在Connection类,也就是说Client类类似于一个前台,可以提供各种服务,而具体的实现则依赖于Connection和Commands,Client提供方法与Jedis基本一致,不同的是Client类里获取命令是没有返回值的,所有我们一般不用Client,都是使用Jedis,不过Jedis底层必须有Client的存在

Client所依赖的接口:
    Commands:
        内部都是Redis基本命令的封装
Client所继承的类:
    BinaryClient:
        用来最终和Redis服务端交互的客户端,以二进制交互,内部继承Connection类

3:Jedis如何发送命令到Redis服务端

  Jedis是通过Socket对Redis服务端进行连接的,而Jedis和Client本身并没有Socket连接方法的实现,相关的连接方法都在Connection类中,观察继承关系,Connection类是其顶层的实现类。Jedis或者Client发送命令时,必须通过Connection类的connect()方法建立TCP连接。
  在使用Connection类时,需提供相关的参数进行实例化,从构造方法可以看到,需要提供主机名,如果不设置,则使用默认名localhost.连接端口,不设置则使用默认端口6379,连接超时时长(如果不进行设置,则默认与socketTimeout保持一致),Socket读取超时时长(如果不进行设置,则使用默认时长2000ms),SSL加密传输则是可选的。在连接时必须判断当前对象的连接状态,如果符合条件则新建Socket实例。
  Jedis和Client类通过Connection对象的sendCommand()方法进行命令传输,在传输命令时必须将字符串转为字节数组,如果类似于ping,ask这样的命令,只需要将命令转为字节即可。转换完成之后写入到输出流中,将字节流发送给Redis 服务端。

三:Jedis操作使用

1:基本案例

  基本案例中我使用maven的一个空项目(maven骨架:maven-archetype-quickstart)来进行简单的操作;

  <!--导入Jedis坐标,用来操作Redis的,主要就这个包-->
  <dependencies>
    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>3.7.0</version>
    </dependency>
    <!--导入fastjson,用于对象的转换JSON格式-->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.78</version>
    </dependency>
  </dependencies>
public static void main(String[] args){
    //创建一个连接
    Jedis jedis = new Jedis("localhost", 6379);
    //ping一下Redis服务端是否在线,成功则返回 “PONG” 反之报错超时
    String ping = jedis.ping();
    //Jedis它实现了各式各样接口,最终汇聚一个类Jedis,它内部封装了全部Redis命令
    //比如下面的”String类型命令set“保存两条数据,保存成功则返回ok
    jedis.set("name","zhangsan");
    jedis.set("age","22");
    //在redis中获取name值
    String name = jedis.get("name");
    System.out.println(name);
    jedis.close();//关闭连接
    
    //也可以直接使用Client,但是我们还是使用Jedis吧,让Jedis底层调用Client吧,我们直接使用是没有返回值的
    Client client = new Client("localhost", 6379);
    client.set("name","lisi");
    client.close();
}

2:Jedis连接池

#最大活动对象数
redis.pool.maxTotal=1000
#最大能够保持idel状态的对象数
redis.pool.maxIdle=100
#最小能够保持idel状态的对象数
redis.pool.minIdle=50
#当池内没有返回对象时,最大等待时间
redis.pool.maxWaitMillis=10000
#当调用borrow Object方法时,是否进行有效性检查
redis.pool.testOnBorrow=true
#当调用return Object方法时,是否进行有效性检查
redis.pool.testOnReturn=true
#“空闲链接”检测线程,检测的周期,毫秒数。如果为负值,表示不运行“检测线程”。默认为-1
redis.pool.timeBetweenEvictionRunsMillis=30000
#向调用者输出“链接”对象时,是否检测它的空闲超时
redis.pool.testWhileIdle=true
# 对于“空闲链接”检测线程而言,每次检测的链接资源的个数。默认为3
redis.pool.numTestsPerEvictionRun=50
#redis服务器的IP
redis.ip=localhost
#redis服务器的Port
redis.port=6379
#连接Redis超时时间秒
redis.timeout=2000
#连接Redis的password,不写则没有密码
redis.password=
jedisPool.properties
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.io.IOException;
import java.io.InputStream;
import java.time.Duration;
import java.util.Properties;

/**
 * @Author AnHui_XiaoYang
 * @Email 939209948@qq.com
 * @Date 2021/10/17 20:44
 * @Description Jedis连接池工具
 */
public class JedisPoolUtils {
    private static JedisPool jedisPool;

    static {
        //类加载时,读取配置文件
        InputStream in = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedisPool.properties");
        //创建Properties对象并关联对象
        Properties pro = new Properties();
        try {
            pro.load(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //创建连接池配置并设置值
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(Integer.parseInt(pro.getProperty("redis.pool.maxTotal")));
        config.setMaxIdle(Integer.parseInt(pro.getProperty("redis.pool.maxIdle")));
        config.setMinIdle(Integer.parseInt(pro.getProperty("redis.pool.minIdle")));
        config.setMaxWaitMillis(Long.parseLong(pro.getProperty("redis.pool.maxWaitMillis")));
        config.setTestOnBorrow(Boolean.parseBoolean(pro.getProperty("redis.pool.testOnBorrow")));
        config.setTestOnReturn(Boolean.parseBoolean(pro.getProperty("redis.pool.testOnReturn")));
        Duration duration = Duration.ofMinutes(Long.parseLong(pro.getProperty("redis.pool.timeBetweenEvictionRunsMillis")));
        config.setTimeBetweenEvictionRuns(duration);
        config.setTestWhileIdle(Boolean.parseBoolean(pro.getProperty("redis.pool.testWhileIdle")));
        config.setNumTestsPerEvictionRun(Integer.parseInt(pro.getProperty("redis.pool.numTestsPerEvictionRun")));
        String host = pro.getProperty("redis.ip");
        Integer port = Integer.valueOf(pro.getProperty("redis.port"));
        Integer timeout = Integer.valueOf(pro.getProperty("redis.timeout"));
        String password = pro.getProperty("redis.password");
        if (password == null || "".equals(password))
            jedisPool = new JedisPool(config, host, port, timeout);
        else
            jedisPool = new JedisPool(config, host, port, timeout, password);
    }

    /**
     * @return 返回一个JedisClient
     */
    public static Jedis getJedisClient() {
        return jedisPool.getResource();
    }
}
JedisPoolUtil连接工具类
    public static void main(String[] args) {
        //平时使用连接池对象即可,每次都重新创建获取会消耗大量时间
        Jedis jedis = JedisPoolUtils.getJedisClient();
        jedis.set("name","zhangsan");
        String s = jedis.get("name");
        System.out.println(s);
        jedis.close();//不用时直接close即可
    }

  总结:现在在项目中一般不会单独引用Jedis了,通常会以SpringBoot集成Redis,通过RedisTemplate模板来操作Redis;具体使用请参考 SpringDataRedis入门到深入

标签:redis,Redis,命令,Client,Jedis,使用,操作,pool
来源: https://www.cnblogs.com/antLaddie/p/15412981.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有