文章目录
- 开放端口号问题
- 引入依赖
- 验证连接
- 通用命令使用
- set 和 get 命令的使用
- exists 和 del 命令的使用
- keys 命令的使用
- expire 和 ttl 命令
- type 命令的使用
- String 类型命令使用
- mset 和 mget 命令
- getrange 和 setrange 命令
- append 命令
- incr 和 decr 命令
- list 类型命令使用
- lpush 和 lrange 命令
- lpop 和 rpop
- llen
- hash 类型命令使用
- hset 和 hget 命令
- hexists 命令
- hdel 命令
- hkeys 和 hvals 命令
- hmget 和 hmset 命令
- set 类型命令使用
- sadd 和 smembers
- sismember
- scard
- spop
- sinter 和 sinterstore
- zset 类型命令使用
- zadd 和 zrange 命令
- zcard 和 zrem 命令
- zscore 和 zrank命令
开放端口号问题
使用 Java 开发代码时,使用的时 IDEA,这个软件是在 Windows 系统上运行的,而我们的 Redis 是在 Linux云服务器上的,如下图:
此时,要想通过我们开发的Redis客户端访问 Linux 云服务器,就要通过”外网ip“进行访问,而且,光修改外网IP还是不够的,因为 Redis 所使用的 6379 端口,默认是被云服务器的防火墙给保护起来了 ,如果要想访问,就需要公开这个端口号,但是注意,这个防火墙最好不要放开,因为,Redis 的端口一旦公开到公网上,就特别容易被入侵,所以,在不开放 Redis 端口号的前提下,又想要跨主机访问,就有以下两种方式:
① 直接让 Java 程序,也在linux上运行,但是这就需要把咱们写好的代码打成可执行的 jar 包,然后把 jar 包部署到 Linux 系统上执行。
② 配置 ssh 端口转发,把云服务的 Redis 端口,映射到本地主机(推荐),这种方案,就可以保证我们既能通过外网访问,又不会产生危险。
我们在 window 系统上,连接 Linux 服务器,都是通过一些终端远程登录到 Linux 服务器上的,例如:xshell ,而在登录时或者是操作Linux服务器时,会用到协议 ssh,通过这个协议/程序,就可以使两台主机进行远程访问。
ssh 协议默认是 22 端口,ssh 协议的功能是非常强大的,其中有一个功能就是能够支持端口转发,相当于通过 ssh 的 22 端口,来传递其他端口的数据
例如,本来我们想要通过 Windows 主机访问云服务器的 6379 端口,于是就构造了一个特殊的 ssh 数据报,把要访问 redis 的请求,放到 ssh 数据报中,通过 22 端口发送给服务器,服务器的 ssh 服务器程序,就能够解析出上述的数据报,然后再把数据报中的数据,交给 6379端口的程序。这个 ssh 就相当于中介。
而在 Linux 主机上,存在的服务器有很多,ssh 程序也可能需要给多个端口传递数据,所以,为了能够区分出给不同的端口传递数据 ,就可以在本地定义一个新的端口号,用来与linux主机上某个端口号产生映射关系,如下图:
通过上述的方式,此时在我们的Java客户端代码上,访问 127.0.0.1:8888 ,就相当于访问 Linux 主机上的 6379 端口了,这个 8888 端口就是 ssh 程序监听的端口。
具体操作如下:
引入依赖
进入maven仓库查找jedis依赖
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.4.6</version>
</dependency>
验证连接
① 连接 Redis 服务器
//1. 连接 Redis
JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");
url中,tcp 表示 reids 在网络通信过程中,使用的是 tcp 协议,并且此处的 url 如果没有使用端口号映射的话,就需要将端口号写成 redis 监听的端口号 6379
② 从连接池中取出一个连接,发送一个 ping 命令,检查 redis 服务器是否在正常运作
//2. 从 redis 池中取出一个连接
try(Jedis resource1 = jedisPool.getResource()) {
String ping = jedis.ping();
System.out.println(ping);
}
Redis ping 命令用于客户端向 Redis 服务器发送一个 PING ,如果服务器运作正常的话,会返回一个 PONG 。 PING 命令不带参数返回 PONG 。 带参数则返回参数 message 。 PING 通常用来测试连接是否存活,或者测试延迟。
注意:这里的代码之所以能够跑通,除了配置 ssh 端口映射外,还有一个要点就是 要配置绑定的 ip 及 关闭保护模式,在 redis 的配置文件中进行设置,如下图:
- 找到 redis 的配置文件 redis.conf
-
编辑配置文件
在新安装的 redis 中,默认绑定的 ip 是 127.0.0.1,此时只能本机访问本机,不能跨主机访问,所以需要进行修改,并且,保护模式默认是 yes,也要改成 no
通用命令使用
下面,我们演示一些 redis 命令在代码中的使用,这里的命令演示,只会演示一部分命令,其他的命令也都是一样的用法。
set 和 get 命令的使用
代码:
public class JedisDemo {
public static void main(String[] args) {
//1. 连接 Redis
JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");
//2. 从 redis 池中取出一个连接
try(Jedis jedis = jedisPool.getResource()) {
test1(jedis);
}
}
private static void test1(Jedis jedis) {
//在进行测试之前,先清空redis数据库,防止残留上一组测试的数据
jedis.flushAll();
//使用 set 和 get 命令
System.out.println("测试 get 和 set 命令");
jedis.set("k1", "111");
String value = jedis.get("k1");
System.out.println("value:" + value);
}
}
set 命令除了上述的基本使用外,还可以配置一些选项,如:设置key的过期时间,设置 nx / xx ,代码如下:
private static void test1(Jedis jedis) {
//在进行测试之前,先清空redis数据库,防止残留上一组测试的数据
jedis.flushAll();
//使用 set 和 get 命令
System.out.println("测试 get 和 set 命令");
SetParams params = new SetParams();
//设置过期时间
params.ex(10);
jedis.set("k1", "111");
String value = jedis.get("k1");
System.out.println("value:" + value);
}
在调用 set 方法时,可以看到多个重载方法,其中就有包含 SetParams 类型的参数,通过该类型对象来进行 选项的设置
exists 和 del 命令的使用
代码:
private static void test2(Jedis jedis) {
System.out.println("演示 exists 和 del 命令");
jedis.set("key1", "111");
//检查 key1 是否存在
boolean result = jedis.exists("key1");
System.out.println("result:" + result);
//删除 key1
long result2 = jedis.del("key1");
System.out.println("result2:" + result2);
//再次检查 key1 是否存在
System.out.println(jedis.exists("key1"));
}
del 命令不仅可以删除一个 key ,也可以删除多个 key
private static void test2(Jedis jedis) {
System.out.println("演示 exists 和 del 命令");
jedis.set("key1", "111");
jedis.set("key2","222");
jedis.set("key3","333");
//删除 key1 key2 key3
long result2 = jedis.del("key1", "key2", "key3");
System.out.println("result2:" + result2);
}
keys 命令的使用
代码:
private static void test3(Jedis jedis) {
System.out.println("演示 keys 命令");
jedis.set("key1", "111");
jedis.set("key2", "222");
jedis.set("key3", "333");
jedis.set("kay", "555");
jedis.set("kby", "666");
//keys 里面的参数就是通配符,按照keys命令的规则获取指定样式的key
Set<String> set = jedis.keys("*");
System.out.println(set.toString());
set = jedis.keys("k[ab]y");
System.out.println(set.toString());
}
expire 和 ttl 命令
代码:
private static void test4(Jedis jedis) throws InterruptedException {
System.out.println("演示 expire 和 ttl 命令");
jedis.flushAll();
jedis.set("key1", "111");
jedis.expire("key1", 10);
Thread.sleep(3000);
long time = jedis.ttl("key1");
System.out.println("time:" + time);
}
type 命令的使用
代码:
private static void test5(Jedis jedis) {
System.out.println("演示 type 命令");
jedis.flushAll();
jedis.set("key1", "111");
String type = jedis.type("key1");
System.out.println("type: " + type);
//设置list类型
jedis.lpush("key2", "111", "222");
type = jedis.type("key2");
System.out.println("type: " + type);
//设置hash类型
jedis.hset("key3", "k1", "1");
type = jedis.type("key3");
System.out.println("type: " + type);
}
String 类型命令使用
mset 和 mget 命令
代码:
private static void test6(Jedis jedis) {
System.out.println("mset 和 mget 命令的使用");
jedis.mset("key1","111", "key2", "222", "key3","333");
List<String> values = jedis.mget("key1", "key2", "key3");
System.out.println("values: " + values.toString());
}
注意:此处的获取多个key中的value的顺序和设置key时的顺序都是匹配的,如果某个key不存在,则使用 null 表示。
getrange 和 setrange 命令
代码:
private static void test7(Jedis jedis) {
System.out.println("getrange 和 setrange");
jedis.set("key1", "abcdefgh");
String result = jedis.getrange("key1", 0, 3);
System.out.println("result: " + result);
jedis.setrange("key1", 0, "qqq");
result = jedis.getrange("key1", 0, -1);
System.out.println("result: " + result);
}
append 命令
代码:
private static void test8(Jedis jedis) {
System.out.println("append 命令");
jedis.flushAll();
jedis.set("key1", "abc");
String result = jedis.get("key1");
System.out.println("result: " + result);
jedis.append("key1", "111");
result = jedis.get("key1");
System.out.println("result: " + result);
}
incr 和 decr 命令
代码:
private static void test9(Jedis jedis) {
System.out.println("incr 和 decr 命令");
jedis.flushAll();
jedis.set("key1", "100");
jedis.incr("key1");
String value = jedis.get("key1");
System.out.println("value: " + value);
jedis.decr("key1");
value = jedis.get("key1");
System.out.println("value: " + value);
}
list 类型命令使用
lpush 和 lrange 命令
代码:
private static void test10(Jedis jedis) {
System.out.println("lpush 和 rpush");
jedis.flushAll();
jedis.lpush("key1", "111", "222", "333");
List<String> reslut = jedis.lrange("key1", 0, -1);
System.out.println("result: " + reslut);
jedis.rpush("key2", "111", "222", "333");
reslut = jedis.lrange("key2", 0, -1);
System.out.println("result: " + reslut);
}
lpop 和 rpop
代码:
private static void test11(Jedis jedis) {
System.out.println("lpop 和 rpop");
jedis.flushAll();
jedis.lpush("key1", "111", "222", "333");
jedis.lpop("key1");
List<String> result = jedis.lrange("key1", 0, -1);
System.out.println("result: " + result);
jedis.rpop("key1");
result = jedis.lrange("key1", 0, -1);
System.out.println("result: " + result);
}
llen
代码:
private static void test12(Jedis jedis) {
System.out.println("llen 命令");
jedis.flushAll();
jedis.lpush("key1", "111", "222", "333");
long key1 = jedis.llen("key1");
System.out.println("key1: " + key1);a
}
hash 类型命令使用
hset 和 hget 命令
代码:
private static void test18(Jedis jedis) {
System.out.println("hset 和 hget");
jedis.flushAll();
//插入元素
jedis.hset("key", "f1", "111");
jedis.hset("key", "f2", "222");
jedis.hset("key", "f3", "333");
//获取元素
String f1 = jedis.hget("key", "f1");
String f2 = jedis.hget("key", "f2");
System.out.println("f1: " + f1);
System.out.println("f2: " + f2);
}
hexists 命令
代码:
private static void test19(Jedis jedis) {
System.out.println("hexists 命令");
jedis.flushAll();
//插入元素
jedis.hset("key", "f1", "111");
jedis.hset("key", "f2", "222");
jedis.hset("key", "f3", "333");
//检查 f1 字段是否存在
boolean f1 = jedis.hexists("key", "f1");
System.out.println("f1: " + f1);
}
hdel 命令
代码:
private static void test20(Jedis jedis) {
System.out.println("hdel 命令");
jedis.flushAll();
//插入元素
jedis.hset("key", "f1", "111");
jedis.hset("key", "f2", "222");
jedis.hset("key", "f3", "333");
//删除字段
long result = jedis.hdel("key", "f1", "f2");
System.out.println("成功删除: " + result);
System.out.println("是否存在: " + jedis.hexists("key", "f1"));
}
hkeys 和 hvals 命令
代码:
private static void test21(Jedis jedis) {
System.out.println("hkeys 和 hvals 命令");
jedis.flushAll();
//插入元素
jedis.hset("key", "f1", "111");
jedis.hset("key", "f2", "222");
jedis.hset("key", "f3", "333");
//获取所有的字段
Set<String> fields = jedis.hkeys("key");
System.out.println("fields: " + fields);
//获取所有字段对应的value
List<String> values = jedis.hvals("key");
System.out.println("values: " + values);
}
hmget 和 hmset 命令
private static void test22(Jedis jedis) {
System.out.println("hmset 和 hmget 命令");
jedis.flushAll();
Map<String, String> map = new HashMap<>();
map.put("f1", "111");
map.put("f2", "222");
map.put("f3", "333");
jedis.hmset("key", map);
//获取指定字段对应的value
List<String> result = jedis.hmget("key", "f1", "f2", "f3");
System.out.println("result: " + result);
}
set 类型命令使用
sadd 和 smembers
代码:
private static void test13(Jedis jedis) {
System.out.println("sadd 和 smemgbers 命令");
jedis.flushAll();
//插入元素
jedis.sadd("key1", "111", "222", "333");
//获取set中所有元素
Set<String> result = jedis.smembers("key1");
System.out.println("result: " + result);
}
sismember
代码:
private static void test16(Jedis jedis) {
System.out.println("sismembers 命令");
jedis.flushAll();
jedis.sadd("key1", "111", "222", "333", "444", "555");
//检查 333 在列表中是否存在
boolean result = jedis.sismember("key1", "333");
System.out.println("reslut: " + result);
}
scard
代码:
private static void test14(Jedis jedis) {
System.out.println("scard 命令");
jedis.flushAll();
jedis.sadd("key1", "111", "222");
//获取列表中的长度
long result = jedis.scard("key1");
System.out.println("result: " + result);
}
spop
代码:
private static void test15(Jedis jedis) {
System.out.println("spop 命令");
jedis.flushAll();
jedis.sadd("key1", "111", "222", "333", "444", "555");
//随机删除
String result1 = jedis.spop("key1");
System.out.println("result1: " + result1) ;
String result2 = jedis.spop("key1");
System.out.println("result2: " + result2);
String result3 = jedis.spop("key1");
System.out.println("result3: " + result3);
}
sinter 和 sinterstore
代码:
private static void test17(Jedis jedis) {
System.out.println("sinter 和 sinterstore 命令");
jedis.flushAll();
jedis.sadd("key1", "111", "222", "333");
jedis.sadd("key2", "111", "222", "444");
//求交集
Set<String> result = jedis.sinter("key1", "key2");
System.out.println("result: " + result);
//求完交集后,存放到key3中
jedis.sinterstore("key3", "key1", "key2");
Set<String> resultOfkey3 = jedis.smembers("key3");
System.out.println("reslultOfKey3: " + resultOfkey3);
}
zset 类型命令使用
zadd 和 zrange 命令
代码:
private static void test23(Jedis jedis) {
System.out.println("zadd 和 zrange 命令");
jedis.flushAll();
//添加元素
jedis.zadd("key", 10, "张三");
//添加多个元素
//添加多个元素时,要先把多个元素放到Map中,并且,在Map中存放分数时,类型必须是double类型
Map<String, Double> map = new HashMap<>();
map.put("李四", 20.0);
map.put("王五", 30.0);
jedis.zadd("key", map);
//获取有序列表中的元素
List<String> result = jedis.zrange("key", 0, -1);
System.out.println("result: " + result);
//获取有序列表中的元素+分数
List<Tuple> result2 = jedis.zrangeWithScores("key", 0, -1);
System.out.println("result2: " + result2);
//获取某一个指定的成员和分数
String member = result2.get(0).getElement();
double score = result2.get(0).getScore();
System.out.println("member: " + member + ",score: " + score);
}
zcard 和 zrem 命令
代码:
private static void test24(Jedis jedis) {
System.out.println("zadd 和 zrange 命令");
jedis.flushAll();
//添加多个元素
//添加多个元素时,要先把多个元素放到Map中,并且,在Map中存放分数时,类型必须是double类型
Map<String, Double> map = new HashMap<>();
map.put("张三", 10.0);
map.put("李四", 20.0);
map.put("王五", 30.0);
jedis.zadd("key", map);
//获取元素个数
long members = jedis.zcard("key");
System.out.println("members: " + members);
//删除元素
long n = jedis.zrem("key", "张三", "李四");
System.out.println("n: " + n);
List<String> result = jedis.zrange("key", 0, -1);
System.out.println("result: " + result);
}
zscore 和 zrank命令
private static void test25(Jedis jedis) {
System.out.println("ascore 和 zrank 命令");
jedis.flushAll();
//添加多个元素
//添加多个元素时,要先把多个元素放到Map中,并且,在Map中存放分数时,类型必须是double类型
Map<String, Double> map = new HashMap<>();
map.put("张三", 10.0);
map.put("李四", 20.0);
map.put("王五", 30.0);
jedis.zadd("key", map);
//根据member获取分数
Double zscore = jedis.zscore("key", "张三");
System.out.println("zscore: " + zscore);
//获取当前指定member的排名
Long zrank = jedis.zrank("key", "张三");
System.out.println("zrank: " + zrank);
}