Redis(十) Java客户端

在这里插入图片描述

前言

前面我们学习 redis 的时候都是在 redis 的原生客户端上输入 redis 命令的,由于 Redis 服务器官网公开了使用的协议——RESP,所有任何一个第三方都可以通过 RESP 协议来实现出一个和 redis 服务器通信的客户端程序。同样我们的 Java 也是。

有很多大佬开发出了相关的库,我们可以直接使用,这样我们程序眼就不必过多关注 RESP 协议的细节了。在 Java 生态中,封装了 RESP 协议实现的客户端有很多,在这里我们介绍的是其中的一个 JEDIS。

SSH端口转发

平时我们使用 Java 开发的时候,往往使用的平台是 Windows,而 Redis 服务器往往是在 Linux 系统上的,所以我们 Windows 用户要想使用 Linux 系统,最简单的方法就是买一个 Linux 云服务器,然后通过第三方软件来远程连接我们的 Linux 云服务器,这个第三方软件通常使用 SSH 协议来连接我们的云服务器的,那么我们的 Java 程序如何访问到我们的云服务上面的 Redis 服务器呢?

很多人可能会说,云服务器不是使用的公网 IP 吗,只要知道我们云服务器的 IP 地址和 Redis 的端口号不就能访问到这台云服务器上面的 Redis 服务器了吗?想法是好的,但是实际上行不通,如果我们放开云服务器的 6379 Redis 服务器端口,这样我们是可以访问到这台云服务器上面的 Redis 服务器,但是可能不出三天,你的这台云服务器就会被黑客给入侵了。既然这样的话,那么我们前面在使用 Java 的 Spring 的时候,要想访问我们写的程序,那么就需要将 Java 程序部署到 Linux 服务器上才能使用,那么这不也开放了 8080 端口吗?那这为什么可以呢?这是因为 Java 使用的端口黑客要是想攻击,需要花费的成本就会很高,而我们的 Redis 服务器使用的端口黑客要是想攻击,成本就相对较低,那么如果我更换 Redis 服务器使用的端口是否能解决这个问题呢?答案是不能的,这样做就相当于只是更换了门的位置,但是门上面的锁没有更换,是一样的。

那么既然这样的话,是否就意味着我们的 Java 程序无法访问到云服务上面的 Redis 服务器吗?这也不是的,为了保证 Java 程序也能访问到云服务器上面的 Redis 服务,有两种解决方法:

  1. 当写完 Java 程序之后,将 Java 程序打成 jar 包,然后部署到云服务器上面,这样客户端和服务器端就在一个机器上了,这样就不容易产生安全问题了。这样虽然可以解决,但是比较麻烦。
  2. 配置 SSH 端口转发

SSH端口转发是一种通过SSH协议在本地和远程主机之间建立安全通道,实现端口之间的数据转发的技术。它允许用户在不直接访问目标主机的情况下,通过安全的SSH连接来访问该主机上的服务。SSH端口转发基于SSH协议的加密和身份验证机制,确保传输的数据安全可靠。

SSH端口转发有两种主要类型:本地端口转发和远程端口转发。本地端口转发将远程计算机上的服务转发到本地计算机,使得本地计算机能够通过SSH隧道访问远程计算机上的服务。而远程端口转发则将本地计算机上的服务转发到远程计算机,实现远程计算机对本地服务的访问。

我们这里使用的是将远程计算机上的服务转发到本地计算机:

我这里使用的是 xshell 来连接我的云服务器,在 xshell 中右击我们要使用的云服务器,然后选择属性:
在这里插入图片描述
选择隧道 -> 添加:

在这里插入图片描述
在这里插入图片描述

确定之后,重启我们的云服务器,并且如果需要使用远程计算机上的服务,需要保证我们的 xshell 和 云服务器是处于连接状态,我们可以在本地计算机上使用 netstat -ano | findstr 8888来查看是否绑定成功。

在这里插入图片描述
如果没有绑定成功,或者 xshell 没有连接上云服务就查找不到这个端口。

不仅如此,为了能使我们的 Java 程序能成功访问到云服务器上的 Redis 服务,我们还需要设置 redis 的配置文件:

在这里插入图片描述

Jedis的使用

当完成 SSH 端口的映射之后,我们就可以说在 Java 程序中访问我们云服务器上的 Redis 服务器了。

首先因为 Jedis 属于第三方库,所以首先需要将 Jedis 的 maven 坐标导入到我们的项目中。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
导入依赖之后,我们就可以使用 Jedis 了。

Redis 通用命令的使用

要想使用 Jedis,首先我们需要先得到一个类似 JedisPool 的池,然后再从这个 JedisPoll 中拿到 Jedis 对象:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class RedisDemoGeneric {
    public static void main(String[] args) {
        JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");
        try (Jedis jedis = jedisPool.getResource()) {
            
        }
    }
}

我们之所以选择 Jedis 作为 Java 的 Redis 客户端,是因为 Jedis 的方法和 Redis 的命令有极大的相似性,这样就降低了我们的学习成本。

test1();

public static void test1(Jedis jedis) {
        jedis.flushAll();  //首先清空数据库,防止每次调用方法的时候,里面的数据造成影响
        String pong = jedis.ping();
        System.out.println(pong);
    }

在这里插入图片描述
这里的红色不是报错,暂时先不用管。

public static void test1(Jedis jedis) {
        jedis.flushAll();  //首先清空数据库,防止每次调用方法的时候,里面的数据造成影响
        String pong = jedis.ping();
        System.out.println(pong);
        jedis.set("key","111");
        String value = jedis.get("key");
        System.out.println(value);
    }

在这里插入图片描述
可以看到这里面有很多种方法:

在这里插入图片描述
如果我们在使用 set 方法的时候需要指定其他选项的时候,可以传入一个 SetParams 类型的参数:

在这里插入图片描述

public static void test1(Jedis jedis) {
        SetParams setParams = new SetParams();
        setParams.ex(30);
        setParams.nx();
        jedis.set("key1","111",setParams);
        long time = jedis.ttl("key1");
        System.out.println(time);
    }

在这里插入图片描述

jedis.set("key","111");
boolean result = jedis.exists("key"); //判断key是否存在
System.out.println("result: " + result);

在这里插入图片描述

jedis.set("key","111");
jedis.set("key2","222");
long del = jedis.del("key"); //删除key
System.out.println("del: " +del);
boolean v1 = jedis.exists("key");
boolean v2 = jedis.exists("key2");
System.out.println("v1: " + v1);
System.out.println("v2: " + v2);

在这里插入图片描述

jedis.set("key1","111");
jedis.set("key2","222");
jedis.set("key3","333");
Set<String> keys = jedis.keys("*"); //对于keys命令的返回值,需要使用set类型来接收,因为redis中key是不可以重复的
System.out.println("keys: " + keys);

在这里插入图片描述

jedis.set("key1","111");
String type = jedis.type("key1");
System.out.println("type: " + type);
jedis.lpush("key2","111","222");
type = jedis.type("key2");
System.out.println("type: " + type);
jedis.hset("key3","f1","111");
type = jedis.type("key3");
System.out.println("type: " + type);
jedis.sadd("key4","111","222");
type = jedis.type("key4");
System.out.println("type: " + type);
jedis.zadd("key5",90.5,"111");
type = jedis.type("key5");
System.out.println("type: " + type);

在这里插入图片描述

Redis String 类型命令的使用

public static void test2(Jedis jedis) {
    jedis.flushAll();

    jedis.mset("key1","111","key2","222","key3","333");
    List<String> list = jedis.mget("key1","key2","key3");
    System.out.println("list: " + list);
}

在这里插入图片描述

jedis.set("key1","abcdefg");
String v = jedis.get("key1");
System.out.println("v: " + v);
jedis.setrange("key1",2,"xyz");
v = jedis.getrange("key1",0,-1);
System.out.println("v: " + v);

在这里插入图片描述

jedis.set("key1","abcdefg");
String v = jedis.get("key1");
System.out.println("v: " + v);
jedis.append("key1","xyz");
v = jedis.get("key1");
System.out.println("v: " + v);

在这里插入图片描述

jedis.set("key1","10");
String v = jedis.get("key1");
System.out.println("v: " + v);
long result = jedis.incr("key1");
System.out.println("result: " + result);
result = jedis.decr("key1");
System.out.println("result: " + result);
result = jedis.incrBy("key1",10);
System.out.println("result: " + result);
result = jedis.decrBy("key1",20);
System.out.println("result: " + result);
double d = jedis.incrByFloat("key1",13.14);
System.out.println("d: " + d);

在这里插入图片描述

Redis List 类型命令使用

jedis.flushAll();

jedis.lpush("key1","111","222","333"); //头插
List<String> list = jedis.lrange("key1",0,-1);
System.out.println("list: " + list);

在这里插入图片描述

jedis.rpush("key1","111","222","333");
List<String> list = jedis.lrange("key1",0,-1);
System.out.println("list: " + list);
String pop = jedis.lpop("key1");
System.out.println("lpop: " + pop);
pop = jedis.rpop("key1");
System.out.println("rpop: " + pop);

在这里插入图片描述

List<String> list = jedis.lrange("key1",0,-1);
System.out.println("list: " + list);
list = jedis.blpop(300,"key1","key2");
System.out.println("list: " + list);

在这里插入图片描述
在这里插入图片描述

Redis Hash 类型命令的使用

jedis.flushAll();

//hset可以一次只设置一对file-value
jedis.hset("key1","f1","111");
String v = jedis.hget("key1","f1");
System.out.println("v: " + v);
//hset也可通过map来一次设置多对file-set
Map<String,String> map = new HashMap<>();
map.put("f1","111");
map.put("f2","222");
jedis.hset("key2",map);
v = jedis.hget("key2","f2");
System.out.println("v: " + v);

在这里插入图片描述

jedis.hset("key1","f1","111");
boolean b = jedis.hexists("key1","f1");
System.out.println("b: " + b);
b = jedis.hexists("key1","key2");
System.out.println("b: " + b);

在这里插入图片描述

jedis.hset("key1","f1","111");
jedis.hdel("key1","f1");
String s = jedis.hget("key1","f1");
System.out.println("s: " + s);

在这里插入图片描述

Map<String,String> map = new HashMap<>();
map.put("f1","111");
map.put("f2","222");
map.put("f3","333");
map.put("f4","444");
jedis.hset("key1",map);
Set<String> set = jedis.hkeys("key1");
System.out.println("keys: " + set);
List<String> list = jedis.hvals("key1");
System.out.println("values: " + list);

在这里插入图片描述

Map<String,String> map = new HashMap<>();
map.put("f1","111");
map.put("f2","222");
map.put("f3","333");
map.put("f4","444");
jedis.hmset("key1",map);
List<String> list = jedis.hmget("key1","f1","f2","f4");
System.out.println("list: " + list);

在这里插入图片描述

Redis Set 类型的使用

jedis.flushAll();

jedis.sadd("key1","111","222","444","333");
Set<String> set = jedis.smembers("key1");
System.out.println("members: " + set);

在这里插入图片描述

jedis.sadd("key1","111","222","444","333");
Set<String> set = jedis.smembers("key1");
boolean b = jedis.sismember("key1","111");
System.out.println("b: " + b);
b = jedis.sismember("key1","10101010");
System.out.println("b: " + b);

在这里插入图片描述

jedis.sadd("key1","111","222","444","333");
long len = jedis.scard("key1");
System.out.println("len: " + len);

在这里插入图片描述

jedis.sadd("key1","111","222","444","333");
String pop = jedis.spop("key1");
System.out.println("pop: " + pop);
pop = jedis.spop("key1");
System.out.println("pop: " + pop);
pop = jedis.spop("key1");
System.out.println("pop: " + pop);
pop = jedis.spop("key1");
System.out.println("pop: " + pop);
pop = jedis.spop("key1");
System.out.println("pop: " + pop);

在这里插入图片描述

jedis.sadd("key1","111","222","444","333");
jedis.sadd("key2","111","222","777","888");
Set<String> set = jedis.sinter("key1","key2");
System.out.println("inter: " + set);

在这里插入图片描述

jedis.sadd("key1","111","222","444","333");
jedis.sadd("key2","111","222","777","888");
long len = jedis.sinterstore("key3","key1","key2");
System.out.println("len: " + len);
Set<String> set = jedis.smembers("key3");
System.out.println("set: " + set);

在这里插入图片描述

Redis Zset 类型命令的使用

jedis.zadd("key1",93.5,"zhangsan");
List<String> list = jedis.zrange("key1",0,-1);
System.out.println("set: " + list);
List<Tuple> tuple = jedis.zrangeWithScores("key1",0,-1);
System.out.println("tuple: " + tuple);

在这里插入图片描述

Map<String,Double> map = new HashMap<>();
map.put("zhangsan",93.0);
map.put("lisi",95.5);
map.put("wangwu",100.0);
jedis.zadd("key1",map);
List<String> list = jedis.zrange("key1",0,-1);
System.out.println("list: " + list);
List<Tuple> tuple = jedis.zrangeWithScores("key1",0,-1);
System.out.println("tuple: " + tuple);

在这里插入图片描述

Map<String,Double> map = new HashMap<>();
map.put("zhangsan",93.0);
map.put("lisi",95.5);
map.put("wangwu",100.0);
jedis.zadd("key1",map);
long len = jedis.zcard("key1");
System.out.println("len: " + len);

在这里插入图片描述

Map<String,Double> map = new HashMap<>();
map.put("zhangsan",93.0);
map.put("lisi",95.5);
map.put("wangwu",100.0);
jedis.zadd("key1",map);
long count = jedis.zrem("key1","zhangsan","lisi");
System.out.println("count: " + count);
List<Tuple> tuple = jedis.zrangeWithScores("key1",0,-1);
System.out.println("tuple: " + tuple);

在这里插入图片描述

Map<String,Double> map = new HashMap<>();
map.put("zhangsan",93.0);
map.put("lisi",95.5);
map.put("wangwu",100.0);
jedis.zadd("key1",map);
Double score = jedis.zscore("key1","zhangsan"); //这里尽量使用包装类,因为如果要获取的分数的元素不在zset中就会返回null,而普通类型double无法接收null
System.out.println("score: " + score);
score = jedis.zscore("key1","zhaoliu");
System.out.println("score: " + score);

在这里插入图片描述

Map<String,Double> map = new HashMap<>();
map.put("zhangsan",93.0);
map.put("lisi",95.5);
map.put("wangwu",100.0);
jedis.zadd("key1",map);
Long rank = jedis.zrank("key1","zhangsan"); //这里同样使用包装类
System.out.println("rank: " + rank);
rank = jedis.zrank("key1","lisi");
System.out.println("rank: " + rank);
rank = jedis.zrank("key1","wangwu");
System.out.println("rank: " + rank);
rank = jedis.zrank("key1","zhaoliu");
System.out.println("rank: " + rank);

在这里插入图片描述
如果我们使用 jedis 的时候遇到了问题,可以去 GitHub 上 jedis 的官方文档去看看。https://github.com/redis/jedis

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不能再留遗憾了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值