Jedis
目录
依赖下载
配置SSH转发
连接到redis服务器
客户端的使用
get / set
exists / del
keys
expire /ttl
type
字符串命令
mget / mset
getrange /setrange
append
incr / decr
列表list
push / pop / lrange
blpop/brpop
llen
集合set
sadd
sismember
scard
spop
sinter
sinterstore
hash
hset / hget
hexists
hdel
hkeys / hvals
有序集合zset
zadd
zcard
zrem
zscore
zrank
依赖下载
前往maven仓库搜索jedis:
https://mvnrepository.com/search?q=jedishttps://mvnrepository.com/search?q=jedis
选择4版本:
然后引入或者下载依赖即可。
这里直接提供了maven的一个jedis地址:
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.4.3</version>
</dependency>
在pom.xml中引入依赖:
配置SSH转发
以xshell为例子:
右键你所选择的会话。选择属性:
然后添加:
然后点击连接。
查看是否生效:
使用netstat命令来访问 8888端口:
- win + r 输入cmd打开命令行。
- 输入: netstat -ano |findstr 8888
说明转发成功。
如果什么都不显示,则表示配置失败。
此时此刻,在后续的本地windows编程中,咱们的java代码就可以通过127.0.0.1:8888来访问我们的redis服务器了。同时外面的客户端是无法直接访问redis的6379端口了。
接下来可以正式编辑代码了。
连接到redis服务器
在java目录中创建一个案例,如下:
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public class RedisDemo {
public static void main(String[] args) {
// 连接到redis 服务器.
JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");
// 从redis池中取出一个连接来
try (Jedis jedis = jedisPool.getResource()) {
// Redis各种命令就对应到Jedis对象的各种方法,调用方法,就相当于执行命令.
String pong = jedis.ping();
System.out.println(pong);
}
}
}
- 首先需要创建一个jedis池,也就是JedisPool类,然后在这个pool中取出连接,来进行执行命令。
- 使用jedisPool中的getResource方法来获取一个jedis连接,返回值为Jedis类型数据,这个Jedis类型的数据就是建立好的一个链接
- 通过这个Jedis连接来进行编写代码,最简单的一个代码用来验证是否连接上了,如上:jedis.ping(),如果返回值为pong,那么说明连接成功,如代码:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
PONG
Process finished with exit code 0
最开始安装Redis的时候,要配置绑定的ip,以及关闭保护模式。下面来看看如何操作:
- 找到Redis的配置文件:redis.conf,然后打开
- 找到bind选项:
这里默认绑定的是127.0.0.1,此时只能本机和本机访问,不能跨主机访问。应该将其改为图所示的0.0.0.0 - 关闭保护模式,首先找到redis.conf配置文件中的protected-mode
这里默认是yes,如果是yes的话就是开启保护模式,跨主机也是不能访问的。将其设置为no。
警告:当前的使用java代码和ssh转发进行的redis服务器访问操作仅限于开发阶段,实际情况就需要根据实际情况来修改ip。
客户端的使用
下面就将介绍jedis中的通用命令:
- get/set
- exists
- del
- keys
- expire /ttl
- type
- ......
接下来的介绍不会覆盖到所有的命令,这里只是介绍到比较重要的、具有代表性的命令进行演示。
get / set
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import javax.swing.*;
public class RedisDemo {
public static void test1(Jedis jedis) {
System.out.println("jedis的get和set的使用");
// 先清空数据库(避免上一组数据对本次测试的影响)
jedis.flushAll(); // 此命令就相当于Redis中的flushall
// 使用set
jedis.set("key","111");
jedis.set("key2","222");
// 进行get
System.out.println("key: " + jedis.get("key"));
System.out.println("key2: "+jedis.get("key2"));
}
public static void main(String[] args) {
// 连接到redis 服务器.
JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");
// 从redis池中取出一个连接来
try (Jedis jedis = jedisPool.getResource()) {
// Redis各种命令就对应到Jedis对象的各种方法,调用方法,就相当于执行命令.
test1(jedis);
}
}
}
注意看,在编写set的时候,你会发现,这里的set有很多重载的方法,例如:
除了指定keyvalue 的方法,还可以设置一个参数,这个参数的类型是SetParams。
首先我们先new一个SetParams,并创建其对象。
可以看见里面提供了很多方法:
- 其中有一个ex的方法可以用于设置超时时间,单位是秒,这里不做过多讲解。
- nx():用于对不存在的数据进行操作,只会添加数据,不会更新数据
- xx():用于已经存在的数据,才能够进行修改。
public static void test1(Jedis jedis) {
System.out.println("jedis的get和set的使用");
// 先清空数据库(避免上一组数据对本次测试的影响)
jedis.flushAll(); // 此命令就相当于Redis中的flushall
// 使用set
SetParams params = new SetParams();
params.ex(10);
params.xx();
jedis.set("key","111",params);
// 进行get
System.out.println(jedis.get("key"));
}
执行test1方法,就会出现:
因为设置了xx参数,代表只会对已经存在的数据进行修改,但是此时的set操作当前的key是不存在的,所以get返回一个空。
exists / del
实例:
public static void test2(Jedis jedis) {
System.out.println("exists 和 del的使用");
jedis.flushAll(); // 此命令就相当于Redis中的flushall
// 首先set两个key
jedis.set("key1","111");
jedis.set("key2","222");
System.out.println(jedis.exists("key1")); // 已经设置,打印true
System.out.println(jedis.exists("key2")); // 已经设置,打印true
System.out.println(jedis.exists("key3")); // 没有设置,打印false
long ret = jedis.del("key1"); // 成功删除key1这一个健,返回1
// del 返回long类型表示成功返回多少个元素.
System.out.println(ret);
// 判定这个被删除的key1是否存在
boolean retEx = jedis.exists("key1"); // 已经被删除,返回false.
System.out.println(retEx);
// 如果要删除多个key: jedis.del("key1","key2","key3", ... )
}
Jedis的方法exists,如果key已经存在,那么返回值为boolean类型的true,如果不存在则返回false。del则是删除已经存在的key,返回值为long类型,表示删除key的个数。
当然del还支持多个key同时删除:
jedis.del("key1","key2","key3", ... )
keys
public static void test3(Jedis jedis) {
System.out.println("keys* 的使用");
jedis.flushAll(); // 此命令就相当于Redis中的flushall
// 设置四个key
jedis.set("key1","1");
jedis.set("key2","2");
jedis.set("key3","3");
jedis.set("key4","4");
// 使用keysm,参数为pattern,通过特定格式的字符串来匹配符合要求的key,其中最简单的就是*,表示匹配任意结果
Set<String> set = jedis.keys("*");
// 这里使用set表示,是因为set里面的key是不能重复的
System.out.println(set);
}
调用test3(),输出:
expire /ttl
public static void test4(Jedis jedis) {
System.out.println("expire / ttl* 的使用");
jedis.flushAll(); // 此命令就相当于Redis中的flushall
jedis.set("key","111");
jedis.expire("key",10); // expire的第一个参数是key,第二个参数是long类型.表示秒
// ttl 判断一个key还有多少过期时间,返回类型为long
long time = jedis.ttl("key");
System.out.println(time);
// 休眠三秒
try {
Thread.sleep(Long.parseLong("3000"));
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
// 再次ttl查看多少秒
System.out.println(jedis.ttl("key"));
}
输出:
这里有延迟,说明服务器有延迟。
- expire:给存活的key设置一个过期时间,有两个参数,第一个参数是key对象,第二个 参数是long类型的数字,表示存活多少秒
- ttl:查看一个key的存活时间,返回类型为long类型,表示还剩多少秒。
type
public static void test5(Jedis jedis) {
System.out.println("type 的使用");
jedis.flushAll(); // 此命令就相当于Redis中的flushall
// type: 查看一个key的value是什么类型
jedis.set("key","111");
String type = jedis.type("key");
System.out.println(type);
jedis.lpush("list","111","222","333");
System.out.println(jedis.type("list"));
}
字符串命令
- get/set
- mget /mset
- getrange和setrange
- append
- incr 、decr
mget / mset
public static void test1(Jedis jedis) {
System.out.println("mget,mset");
jedis.flushAll();
jedis.mset("key1","111","key2","222","key3","333");
// 返回值为 List<String>
List<String> list = jedis.mget("key1","key2","key3","key100");
System.out.println("values:" + list);
}
输出:
如果没有找到,那么使用null来表示。
getrange /setrange
public static void test2(Jedis jedis) {
System.out.println("mget,mset");
jedis.flushAll();
jedis.set("key","0123456789");
// 有三个参数,第一个参数用来指定key,第二个和第三个参数用来指定范围,类型都是long,这里的下标可以理解为字符串的charAt()
System.out.println(jedis.getrange("key", 0, 4));
System.out.println(jedis.getrange("key",1,8));
jedis.setrange("key",9,"xxx");
System.out.println(jedis.get("key"));
}
append
public static void test3(Jedis jedis) {
System.out.println("append");
jedis.flushAll();
jedis.set("key","abcdef");
jedis.append("key","ghijk");
String val = jedis.get("key");
System.out.println(val);
}
输出:
incr / decr
public static void test4(Jedis jedis) {
System.out.println("incr / decr");
jedis.flushAll();
jedis.set("key","100");
long ret = jedis.incr("key");
System.out.println(ret);
ret = jedis.decr("key");
System.out.println(ret);
}
输出:
- 他们两个的返回值都是执行命令之后的结果。
- 除了incr和decr之外,还有很多,例如:
这些就不做过多的讲解,可以自己参考上面的例子进行演示。
列表list
- lpush / lpop / lrange
- rpush / rpop
- blpop / brpop
- llen
push / pop / lrange
public static void test1(Jedis jedis) {
System.out.println("lpush 和 lrange");
jedis.flushAll();
// 头插
jedis.lpush("key","111","222","333","444");
// 尾插
jedis.rpush("key","000");
List<String> list = jedis.lrange("key",0,-1);
System.out.println(list);
// 弹出444和000
jedis.lpop("key");
jedis.rpop("key");
list = jedis.lrange("key",0,-1);
System.out.println(list);
}
输出:
blpop/brpop
首先创建一个延迟100秒的brpop并执行:
public static void test2(Jedis jedis) {
System.out.println("brpop");
jedis.flushAll();
// 返回结果是一个二元组,一个是从哪个key对应的list中删除,另外一个是删除的是什么
List<String> list = jedis.brpop(100,"key");
System.out.println(list);
}
首先输出:
然后在设置的100s内,打开redis客户端,set一个key:
此时idea控制台输出:
["key","111"]
blpop同理。
llen
求列表的长度:
public static void test3(Jedis jedis) {
System.out.println("llen");
jedis.flushAll();
jedis.lpush("key","111","222","333");
long len = jedis.llen("key");
System.out.println(len);
}
输出:
- llen返回值为long类型。
- 返回值表示列表中元素的个数。
集合set
- sadd, smembers
- sismember
- scard
- spop
- sinter, sinterstore
sadd
public class JedisSet {
public static void test1(Jedis jedis) {
System.out.println("sadd");
jedis.flushAll();
jedis.sadd("key","1","2","3","4");
Set<String> set = jedis.smembers("key");
System.out.println(set);
}
public static void main(String[] args) {
JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");
try(Jedis jedis = jedisPool.getResource()) {
test1(jedis);
}
}
}
输出:
sismember
public static void test2(Jedis jedis) {
System.out.println("sadd");
jedis.flushAll();
long ret = jedis.sadd("key","1","2","3","4");
System.out.println(jedis.sismember("key", "1"));
System.out.println(jedis.sismember("key", "10"));
}
scard
public static void test3(Jedis jedis ){
System.out.println("scard");
jedis.flushAll();
long ret = jedis.sadd("key","1","2","3","4");
long nums = jedis.scard("key");
System.out.println(nums);
}
spop
public static void test4(Jedis jedis) {
System.out.println("spop");
jedis.flushAll();
long ret = jedis.sadd("key","1","2","3","4");
String res = jedis.spop("key");
System.out.println(res);
}
输出:
sinter
public static void test5(Jedis jedis) {
System.out.println("sinter");
jedis.flushAll();
jedis.sadd("key1","1","2","3");
jedis.sadd("key2","2","3","4");
Set<String> set = jedis.sinter("key1","key2");
System.out.println(set);
}
sinterstore
public static void test6(Jedis jedis) {
System.out.println("sinterstore");
jedis.flushAll();
jedis.sadd("key1","1","2","3");
jedis.sadd("key2","2","3","4");
long nums = jedis.sinterstore("key3","key1","key2");
System.out.println(nums);
System.out.println(jedis.smembers("key3"));
}
hash
- hset / hget
- hexists
- hdel
- hkeys
- hvals
- hmget / hmset
hset / hget
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import java.util.HashMap;
import java.util.Map;
public class JedisHash {
public static void testHgetAndHset(Jedis jedis) {
System.out.println("hset和hget");
jedis.flushAll();
// 每次都只设置一次 key的filed和value
jedis.hset("key","f1","v1");
jedis.hset("key","f2","v2");
jedis.hset("key","f3","v3");
jedis.hset("key","f4","v4");
// 一次性设置多个key的field
Map<String, String> map = new HashMap<>();
map.put("f5","v5");
map.put("f6","v6");
jedis.hset("key",map);
// 获取
String res = jedis.hget("key","f1");
System.out.println(res);
// 尝试获取不存在的
res = jedis.hget("key","f100");
System.out.println(res);
}
public static void main(String[] args) {
JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");
try(Jedis jedis = jedisPool.getResource()) {
testHgetAndHset(jedis);
}
}
}
输出:
hexists
public static void testHexists(Jedis jedis) {
System.out.println("hexists");
jedis.flushAll();
jedis.hset("key","f1","v1");
jedis.hset("key","f2","v2");
jedis.hset("key","f3","v3");
System.out.println(jedis.hexists("key","f1"));
System.out.println(jedis.hexists("key","f2"));
System.out.println(jedis.hexists("key","f100"));
}
hdel
public static void testHdel(Jedis jedis) {
System.out.println("hdel");
jedis.flushAll();
jedis.hset("key","f1","v1");
jedis.hset("key","f2","v2");
jedis.hset("key","f3","v3");
// 删除key中的f3
jedis.hdel("key","f3");
// 使用hexists查看是否存在
System.out.println(jedis.hexists("key", "f3"));
// 同时hdel可以同时删除多个
long ret = jedis.hdel("key","f1","f2");
System.out.println(jedis.hexists("key", "f1"));
System.out.println(jedis.hexists("key", "f2"));
System.out.println("一共被删除" + ret + "个field");
}
hkeys / hvals
public static void testHkeysAndHvals(Jedis jedis) {
System.out.println("hkeys and hvals");
jedis.flushAll();
jedis.hset("key","f1","v1");
jedis.hset("key","f2","v2");
jedis.hset("key","f3","v3");
// 使用hkeys获取所有的key
System.out.println("获取所有的key");
Set<String> set = jedis.hkeys("key");
System.out.println(set);
// 使用hvals获取所有的val
System.out.println("获取所有的val");
List<String> list = jedis.hvals("key");
System.out.println(list);
}
有序集合zset
- zadd
- zrange
- zcard
- zrem
- zscore
- zrank
zadd
public static void testZaddAndZrange(Jedis jedis) {
System.out.println("zadd / zrange");
jedis.flushAll();
// 一次性添加一个元素
jedis.zadd("key", 10.0,"zhangsan");
// 一次性添加多个元素
Map<String,Double> map = new HashMap<>();
map.put("lisi",11.3);
map.put("wangwu",13.5);
jedis.zadd("key",map);
// 使用zrange查看
List<String> list = jedis.zrange("key",0, -1);
System.out.println(list);
// 携带分数score:zrangeWithScores
List<Tuple> listWithScores = jedis.zrangeWithScores("key", 0, -1);
System.out.println(listWithScores);
// 获取listWithScores中的元素
String member = listWithScores.get(0).getElement();
double score = listWithScores.get(0).getScore();
System.out.println("member:" + member + ",score:" + score);
}
- Tuple是Jedis或者说是Redis依赖中所携带的类,不是java本身自带的库.
Jedis中的Tuple类是一个用于存储键值对的简单数据结构。它包含两个泛型字段:key和value。key字段用于存储键,而value字段用于存储与键关联的值。Tuple类主要用于在Redis中存储和操作键值对数据。
以下是一个简单的示例:
import redis.clients.jedis.Tuple;
public class JedisTupleExample {
public static void main(String[] args) {
// 创建一个Tuple对象
Tuple<String, String> tuple = new Tuple<>("name", "张三");
// 获取键和值
String key = tuple.getKey();
String value = tuple.getValue();
System.out.println("Key: " + key);
System.out.println("Value: " + value);
}
}
在这个示例中,我们创建了一个包含键"name"和值"张三"的Tuple对象。然后,我们使用getKey()和getValue()方法分别获取键和值,并将它们打印到控制台。
下面是Tuple的原码:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package redis.clients.jedis.resps;
import java.util.Arrays;
import java.util.Objects;
import redis.clients.jedis.util.ByteArrayComparator;
import redis.clients.jedis.util.SafeEncoder;
public class Tuple implements Comparable<Tuple> {
private byte[] element;
private Double score;
public Tuple(String element, Double score) {
this(SafeEncoder.encode(element), score);
}
public Tuple(byte[] element, Double score) {
this.element = element;
this.score = score;
}
public int hashCode() {
int prime = true;
int result = 1;
result = 31 * result;
if (null != this.element) {
byte[] var3 = this.element;
int var4 = var3.length;
for(int var5 = 0; var5 < var4; ++var5) {
byte b = var3[var5];
result = 31 * result + b;
}
}
long temp = Double.doubleToLongBits(this.score);
result = 31 * result + (int)(temp ^ temp >>> 32);
return result;
}
public boolean equals(Object obj) {
if (obj == null) {
return false;
} else if (obj == this) {
return true;
} else if (!(obj instanceof Tuple)) {
return false;
} else {
Tuple other = (Tuple)obj;
return !Arrays.equals(this.element, other.element) ? false : Objects.equals(this.score, other.score);
}
}
public int compareTo(Tuple other) {
return compare(this, other);
}
public static int compare(Tuple t1, Tuple t2) {
int compScore = Double.compare(t1.score, t2.score);
return compScore != 0 ? compScore : ByteArrayComparator.compare(t1.element, t2.element);
}
public String getElement() {
return null != this.element ? SafeEncoder.encode(this.element) : null;
}
public byte[] getBinaryElement() {
return this.element;
}
public double getScore() {
return this.score;
}
public String toString() {
return '[' + SafeEncoder.encode(this.element) + ',' + this.score + ']';
}
}
里面提供了两个比较关键的数据一个是element,也就是member,另外一个就是score,也就是分数.
zcard
public static void testZcard(Jedis jedis) {
System.out.println("zcard");
jedis.flushAll();
Map<String,Double> map = new HashMap<>();
map.put("lisi",11.3);
map.put("wangwu",13.5);
map.put("zhangsan", 10.5);
jedis.zadd("key",map);
long ret = jedis.zcard("key");
System.out.println(ret);
}
zrem
public static void testZrem(Jedis jedis) {
System.out.println("zrem");
jedis.flushAll();
Map<String,Double> map = new HashMap<>();
map.put("lisi",11.3);
map.put("wangwu",13.5);
map.put("zhangsan", 10.5);
jedis.zadd("key",map);
long n = jedis.zrem("key","zhangsan");
System.out.println("删除的个数:" + n);
System.out.println(jedis.zrangeWithScores("key", 0, -1));
}
zscore
public static void testZscore(Jedis jedis) {
System.out.println("zscore");
jedis.flushAll();
Map<String,Double> map = new HashMap<>();
map.put("lisi",11.3);
map.put("wangwu",13.5);
map.put("zhangsan", 10.5);
jedis.zadd("key",map);
double ret = jedis.zscore("key","lisi");
System.out.println(ret);
ret = jedis.zscore("key","wangwu");
System.out.println(ret);
ret = jedis.zscore("key","zhangsan");
System.out.println(ret);
}
zrank
public static void testZrank(Jedis jedis) {
System.out.println("zrank");
jedis.flushAll();
Map<String,Double> map = new HashMap<>();
map.put("lisi",11.3);
map.put("wangwu",13.5);
map.put("zhangsan", 10.5);
jedis.zadd("key",map);
long rankLisi = jedis.zrank("key","lisi");
long rankwangwu = jedis.zrank("key","wangwu");
long rankzhangsan = jedis.zrank("key","zhangsan");
System.out.println("lisi分数:" + jedis.zscore("key","lisi") + ", 排名:" +rankLisi);
System.out.println("wangwu分数:" + jedis.zscore("key","wangwu") + ", 排名:" +rankwangwu);
System.out.println("zhangsan分数:" + jedis.zscore("key","zhangsan") + ", 排名:" +rankzhangsan);
}
如果指定一个不存在的member,会出现异常:
Exception in thread "main" java.lang.NullPointerException
at JedisZset.testZrank(JedisZset.java:96)
at JedisZset.main(JedisZset.java:110)
本章完结 ... ..