Java客户端 Jedis
Posted 木兮同学
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java客户端 Jedis相关的知识,希望对你有一定的参考价值。
获取Jedis
- 添加maven依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.2</version>
</dependency>
Jedis的基本使用
- 演示获取 Jedis 对象,进行简单地set、get操作,要注意开发中关闭不用的连接资源。
Jedis jedis = null;
try {
// 1. 生成一个Jedis对象,这个对象负责和指定Redis实例进行通信
jedis = new Jedis("127.0.0.1", 6379);
// 2. jedis执行set操作
jedis.set("hello", "world");
// 3. jedis执行get操作, value="world"
String value = jedis.get("hello");
System.out.println(value);
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
if (jedis != null) {
jedis.close();
}
}
- Jedis 操作其他五种数据结构演示
// 1.string
// 输出结果:OK
jedis.set("hello", "world");
// 输出结果:world
jedis.get("hello");
// 输出结果:1
jedis.incr("counter");
// 2.hash
jedis.hset("myhash", "f1", "v1");
jedis.hset("myhash", "f2", "v2");
// 输出结果:{f1=v1, f2=v2}
jedis.hgetAll("myhash");
// 3.list
jedis.rpush("mylist", "1");
jedis.rpush("mylist", "2");
jedis.rpush("mylist", "3");
// 输出结果:[1, 2, 3]
jedis.lrange("mylist", 0, -1);
// 4.set
jedis.sadd("myset", "a");
jedis.sadd("myset", "b");
jedis.sadd("myset", "a");
// 输出结果:[b, a]
jedis.smembers("myset");
// 5.zset
jedis.zadd("myzset", 99, "tom");
jedis.zadd("myzset", 66, "peter");
jedis.zadd("myzset", 33, "james");
// 输出结果:[[["james"],33.0], [["peter"],66.0], [["tom"],99.0]]
jedis.zrangeWithScores("myzset", 0, -1);
- 参数除了可以是字符串,Jedis还提供了字节数组的参数,例如:
public String set(final String key, String value)
public String set(final byte[] key, final byte[] value)
public byte[] get(final byte[] key)
public String get(final String key)
- 有了这些API的支持,就可以将Java对象序列化为二进制,当应用需要获取Java对象时,使用 get(final byte[]key) 函数将字节数组取出,然后反序列化为Java对象即可。
Jedis连接池使用
- Jedis直连方式和连接池方式对比
上面是 Jedis 的直连方式,所谓直连是指Jedis每次都会新建TCP连接,使用后再断开连接,对于频繁访问Redis的场景显然不是高效的使用方式,因此
生产环境中一般使用连接池的方式对Jedis连接进行管理
。
方式 | 优点 | 缺点 |
---|---|---|
直连 | 简单方便,适用于少量长期连接的场景 | 1.存在每次新建/关闭TCP连接开销 2.资源无法控制,极端情况会出现连接泄漏 3. Jedis 对象线程不安全 |
连接池 | 1.无需每次连接都生成 Jedis 对象,降低开销 2.使用连接池的形式保护和控制资源的使用 | 相对于直连使用相对麻烦,尤其在资源的管理上需要很多参数来保证,一旦规划不合理也会出现问题 |
- 连接池方式使用
// common-pool连接池配置,这里使用默认配置,后面小节会介绍具体配置说明
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
// 初始化Jedis连接池
JedisPool jedisPool = new JedisPool(poolConfig, "127.0.0.1", 6379);
Jedis jedis = null;
try {
// 1. 从连接池获取jedis对象
jedis = jedisPool.getResource();
// 2. 执行操作
jedis.get("hello");
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
if (jedis != null) {
// 如果使用JedisPool,close操作不是关闭连接,代表归还连接池
jedis.close();
}
}
Jedis中Pipeline使用
前面介绍了 Pipeline 能够将一组Redis命令进行组装,通过一次RTT传输给Redis,再将这组Redis命令的执行结果按顺序返回给客户端。
- 比如来实现一个批量删除 mdel 的操作,实际上Redis提供了mget、mset方法,但是并没有提供mdel方法
Jedis jedis = new Jedis("127.0.0.1");
// 1)生成pipeline对象
Pipeline pipeline = jedis.pipelined();
// 2)pipeline执行命令,注意此时命令并未真正执行
for (String key : keys) {
pipeline.del(key);
}
// 3)执行命令
pipeline.sync();
- 除了
pipeline.sync()
,还可以使用pipeline.syncAndReturnAll()
将pipeline的命令进行返回,例如下面代码将set和incr做了一次pipeline操作,并顺序打印了两个命令的结果
Jedis jedis = new Jedis("127.0.0.1");
Pipeline pipeline = jedis.pipelined();
pipeline.set("hello", "world");
pipeline.incr("counter");
List<Object> resultList = pipeline.syncAndReturnAll();
for (Object object : resultList) {
System.out.println(object);
}
Jedis的Lua脚本使用
- Jedis中执行Lua脚本和redis-cli十分类似,Jedis提供了三个重要的函数实现Lua脚本的执行
Object eval(String script, int keyCount, String... params)
Object evalsha(String sha1, int keyCount, String... params)
String scriptLoad(String script)
eval函数
- script:Lua脚本内容
- keyCount:键的个数
- params:相关参数KEYS和ARGV
scriptLoad和evalsha函数
要一起使用- scriptSha:脚本的SHA1
- keyCount:键的个数
- params:相关参数KEYS和ARGV
// 首先使用scriptLoad将脚本加载到Redis中
String scriptSha = jedis.scriptLoad(script);
String key = "hello";
Object result = jedis.evalsha(scriptSha, 1, key);
// 打印结果为world
System.out.println(result);
以上是关于Java客户端 Jedis的主要内容,如果未能解决你的问题,请参考以下文章