Redis-使用Jedis操作

Jedis提供了JedisPool这个类作为对Jedis的连接池,同时使用了Apache的通用对象池工具common-pool作为资源的管理工具,下面是使用JedisPool操作Redis的代码示例:

1.Jedis连接池(通常JedisPool是单例的)

GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
JedisPool jedisPool = new JedisPool(poolConfig, "127.0.0.1", 6379);

2.获取Jedis对象不再是直接生成一个Jedis对象,而是直接从连接池里获取

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Jedis jedis = null;
try {
// 1. 从连接池获取 jedis 对象
jedis = jedisPool.getResource();
// 2. 执行操作
jedis.get("hello");
} catch (Exception e) {
} finally {
if (jedis != null) {
// 如果使用 JedisPool , close 操作不是关闭连接,代表归还连接池
jedis.close();


}
}

这里可以看到在finally中依然是jedis.close()操作,为什么会把连接关闭呢,这不和连接池的原则违背了吗?但实际上Jedis的close()实现方式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
public void close() {
// 使用 Jedis 连接池
if (dataSource != null) {
if (client.isBroken()) {
this.dataSource.returnBrokenResource(this);
} else {
this.dataSource.returnResource(this);
}
// 直连
} else {
client.close();
}
}

参数说
dataSource!=null代表使用的是连接池,所以jedis.close()代表归还 连接给连接池,而且Jedis会判断当前连接是否已经断开。
dataSource=null代表直连,jedis.close()代表关闭连接。

前面GenericObjectPoolConfig使用的是默认配置,实际它提供有很多参数,例如池子中最大连接数、最大空闲连接数、最小空闲连接数、连接活性检测,等等,例如下面代码:
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
// 设置最大连接数为默认值的 5 倍
poolConfig.setMaxTotal(GenericObjectPoolConfig.DEFAULT_MAX_TOTAL * 5);
// 设置最大空闲连接数为默认值的 3 倍
poolConfig.setMaxIdle(GenericObjectPoolConfig.DEFAULT_MAX_IDLE * 3);
// 设置最小空闲连接数为默认值的 2 倍
poolConfig.setMinIdle(GenericObjectPoolConfig.DEFAULT_MIN_IDLE * 2);
// 设置开启 jmx 功能
poolConfig.setJmxEnabled(true);
// 设置连接池没有连接后客户端的最大等待时间 ( 单位为毫秒 )
poolConfig.setMaxWaitMillis(3000);

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static Jedis getRedisConnect() {
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
// 设置最大连接数为默认值的 5 倍
poolConfig.setMaxTotal(GenericObjectPoolConfig.DEFAULT_MAX_TOTAL * 5);
// 设置最大空闲连接数为默认值的 3 倍
poolConfig.setMaxIdle(GenericObjectPoolConfig.DEFAULT_MAX_IDLE * 3);
// 设置最小空闲连接数为默认值的 2 倍
poolConfig.setMinIdle(GenericObjectPoolConfig.DEFAULT_MIN_IDLE * 2);
// 设置开启 jmx 功能
poolConfig.setJmxEnabled(true);
// 设置连接池没有连接后客户端的最大等待时间 ( 单位为毫秒 )
poolConfig.setMaxWaitMillis(3000);
JedisPool jedisPool = new JedisPool(poolConfig, "127.0.0.1", 6379);
Jedis jedis = jedisPool.getResource();
return jedis;
}

Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
maven项目
pom.xml
<dependencies>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
</dependencies>

Java demo

1
2
3
4
5
6
7
8
9
10
11
public class Demo01 {
@Test
public void testRedis() throws Exception {
Jedis jedis = new Jedis("192.168.18.140",6379);
List<String> list = jedis.mget("user");
for (String string : list) {
System.out.println(string);
}
jedis.close();
}
}

连接不到Redis,是因为在redis3.2之后,redis增加了protected-mode,在这个模式下,即使注释掉了bind 127.0.0.1,再访问redisd时候还是报错。

#bind 127.0.0.1
protected-mode 修改为no
protected-mode no

测试没问题
zhangsanfeng
100

相关操作方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// 连接redis ,redis的默认端口是6379
Jedis jedis = new Jedis("ip", 6379);

// 验证密码,如果没有设置密码这段代码省略
jedis.auth("password");jedis.connect();// 连接
jedis.disconnect();// 断开连接

Set<String> keys = jedis.keys("*"); // 列出所有的key
Set<String> keys = jedis.keys("key"); // 查找特定的key

// 移除给定的一个或多个key,如果key不存在,则忽略该命令.
jedis.del("key1");jedis.del("key1","key2","key3","key4","key5");

// 移除给定key的生存时间(设置这个key永不过期)
jedis.persist("key1");

//检查给定key是否存在
jedis.exists("key1");

// 将key改名为newkey,当key和newkey相同或者key不存在时,返回一个错误
jedis.rename("key1","key2");

// 返回key所储存的值的类型。
// none(key不存在),string(字符串),list(列表),set(集合),zset(有序集),hash(哈希表)
jedis.type("key1");

// 设置key生存时间,当key过期时,它会被自动删除。
jedis.expire("key1",5);// 5秒过期


// 字符串值value关联到key。
jedis.set("key1","value1");


// 将值value关联到key,并将key的生存时间设为seconds(秒)。
jedis.setex("foo",5,"haha");


// 清空所有的key
jedis.flushAll();


// 返回key的个数
jedis.dbSize();


// 哈希表key中的域field的值设为value。
jedis.hset("key1","field1","field1-value");jedis.hset("key1","field2","field2-value");


Map map = new HashMap();map.put("field1","field1-value");map.put("field2","field2-value");jedis.hmset("key1",map);


// 返回哈希表key中给定域field的值
jedis.hget("key1","field1");


// 返回哈希表key中给定域field的值(多个)
List list = jedis.hmget("key1","field1","field2");for(
int i = 0;i<list.size();i++)
{
System.out.println(list.get(i));
}


// 返回哈希表key中所有域和值
Map<String, String> map = jedis.hgetAll("key1");for(
Map.Entry entry:map.entrySet())
{
System.out.print(entry.getKey() + ":" + entry.getValue() + "\t");
}


// 删除哈希表key中的一个或多个指定域
jedis.hdel("key1","field1");jedis.hdel("key1","field1","field2");


// 查看哈希表key中,给定域field是否存在。
jedis.hexists("key1","field1");


// 返回哈希表key中的所有域
jedis.hkeys("key1");


// 返回哈希表key中的所有值
jedis.hvals("key1");


// 将值value插入到列表key的表头。
jedis.lpush("key1","value1-0");jedis.lpush("key1","value1-1");jedis.lpush("key1","value1-2");


// 返回列表key中指定区间内的元素,区间以偏移量start和stop指定.
// 下标(index)参数start和stop从0开始;
// 负数下标代表从后开始(-1表示列表的最后一个元素,-2表示列表的倒数第二个元素,以此类推)
List list = jedis.lrange("key1", 0, -1);// stop下标也在取值范围内(闭区间)
for(
int i = 0;i<list.size();i++)
{
System.out.println(list.get(i));
}


// 返回列表key的长度。
jedis.llen("key1")


// 将member元素加入到集合key当中。
jedis.sadd("key1","value0");jedis.sadd("key1","value1");


// 移除集合中的member元素。
jedis.srem("key1","value1");


// 返回集合key中的所有成员。
Set set = jedis.smembers("key1");


// 判断元素是否是集合key的成员
jedis.sismember("key1","value2");


// 返回集合key的元素的数量
jedis.scard("key1");


// 返回一个集合的全部成员,该集合是所有给定集合的交集
jedis.sinter("key1","key2");


// 返回一个集合的全部成员,该集合是所有给定集合的并集
jedis.sunion("key1","key2");


// 返回一个集合的全部成员,该集合是所有给定集合的差集
jedis.sdiff("key1","key2");