Redis介绍 && Java客户端操作Redis
本文内容
- redis介绍
- redis的 shell 客户端简介
- redis的 java 客户端简介
环境配置
- redis 2.8.17 64bit
- JDK1.6
redis介绍
大多数时候,我们都将 redis 称作是内存数据库,它在运行过程中,将键值对信息存储在内存中,同时在后台以异步的形式写入本地数据库中(默认是:dump.rdb,在 redis.conf 中配置,如果需要考虑安全的持久化需求需要开启 AOF 功能,详细介绍可以查看这篇文章 : redis持久化),redis中存储的 key 可以是任意类型,最后都会存储为 byte[] 类型;value 有多种类型 : string、list、set、sortedset、hash,基本上能够满足在开发中的键值存储需求;此外,redis还支持事务、消息系统等功能,而且提供了各种客户端的 API,如 Java、Python、Shell 等等。
redis的 shell 客户端简介
启动 shell 客户端之前,我们需要打开 redis 服务,redis 默认端口是6379,这个配置也是位于 redis.conf 中。登陆 redis 客户端的方法是 : redis-cli -h 127.0.0.1 -p 6379 (-h 是主机地址, -p 是 redis 服务端口号,由于本文介绍单机环境的 redis,我们可以直接采用默认的配置,那么登陆的方式可以简化为 : redis-cli),当我们打开了 shell 客户端之后,我们可以去 “Ping” 一下,如果返回 “PONG”,那么代表 redis 服务是处于健康状态的。
Redis中每个数据库对外都是一个从0开始的递增数字命名,Redis默认支持16个数据库,可以通过配置参数databases来修改这一数字。客户端与Redis建立连接后会自动选择0号数据库,不过可以随时使用SELECT命令更换数据库。
之前说过,redis 的 value 支持许多种类型,redis 对于每一种存储类型都有不同的 shell 客户端 api,这里,我们对各种 value 的类型 api 进行介绍:
- String类型
String api | 功能描述 |
---|---|
set(key, value) | 给数据库中名称为key的string赋予值value |
get(key) | 返回数据库中名称为key的string的value |
getset(key, value) | 给名称为key的string赋予上一次的value |
mget(key1, key2,…, key N) | 返回库中多个string的value |
setnx(key, value) | 添加string,名称为key,值为value |
setex(key, time, value) | 向库中添加string,设定过期时间time |
mset(key N, value N) | 批量设置多个string的值 |
msetnx(key N, value N) | 如果所有名称为key i的string都不存在 |
incr(key) | 名称为key的string增1操作 |
incrby(key, integer) | 名称为key的string增加integer |
decr(key) | 名称为key的string减1操作 |
decrby(key, integer) | 名称为key的string减少integer |
append(key, value) | 名称为key的string的值附加value |
substr(key, start, end) | 返回名称为key的string的value的子串 |
- List类型
List api | 功能描述 |
---|---|
rpush(key, value) | 在名称为key的list尾添加一个值为value的元素 |
lpush(key, value) | 在名称为key的list头添加一个值为value的 元素 |
llen(key) | 返回名称为key的list的长度 |
lrange(key, start, end) | 返回名称为key的list中start至end之间的元素 |
ltrim(key, start, end) | 截取名称为key的list |
lindex(key, index) | 返回名称为key的list中index位置的元素 |
lset(key, index, value) | 给名称为key的list中index位置的元素赋值 |
lrem(key, count, value) | 删除count个key的list中值为value的元素 |
lpop(key) | 返回并删除名称为key的list中的首元素 |
rpop(key) | 返回并删除名称为key的list中的尾元素 |
blpop(key1, key2,… key N, timeout) | lpop命令的block版本 |
brpop(key1, key2,… key N, timeout) | rpop的block版本 |
- Set类型
List api | 功能描述 |
---|---|
sadd(key, member) | 向名称为key的set中添加元素member |
srem(key, member) | 删除名称为key的set中的元素member |
spop(key) | 随机返回并删除名称为key的set中一个元素 |
smove(srckey, dstkey, member) | 移到集合元素 |
scard(key) | 返回名称为key的set的基数 |
sismember(key, member) | member是否是名称为key的set的元素 |
sinter(key1, key2,…key N) | 求交集 |
sunion(key1, (keys)) | 求并集 |
sdiff(key1, (keys)) | 求差集 |
sinterstore(dstkey, (keys)) | 求交集并将交集保存到dstkey的集合 |
sunionstore(dstkey, (keys)) | 求并集并将并集保存到dstkey的集合 |
sdiffstore(dstkey, (keys)) | 求差集并将差集保存到dstkey的集合 |
smembers(key) | 返回名称为key的set的所有元素 |
srandmember(key) | 随机返回名称为key的set的一个元素 |
- Hash类型
Hash api | 功能描述 |
---|---|
hset(key, field, value) | 向名称为key的hash中添加元素field |
hget(key, field) | 返回名称为key的hash中field对应的value |
hmget(key, (fields)) | 返回名称为key的hash中field i对应的value |
hmset(key, (fields)) | 向名称为key的hash中添加元素field |
hincrby(key, field, integer) | 将名称为key的hash中field的value增加integer |
hexists(key, field) | 名称为key的hash中是否存在键为field的域 |
hdel(key, field) | 删除名称为key的hash中键为field的域 |
hlen(key) | 返回名称为key的hash中元素个数 |
hkeys(key) | 返回名称为key的hash中所有键 |
hvals(key) | 返回名称为key的hash中所有键对应的value |
hgetall(key) | 返回名称为key的hash中所有的键(field)及其对应的value |
除了针对 value 类型的 api 之外,还有一些常用的公共 api,如下:
常用 api | 功能描述 |
---|---|
quit | 关闭连接(connection) |
type(key) | 返回值的类型 |
del(key) | 删除一个key |
exists(key) | 确认一个key是否存在 |
keys(pattern) | 返回满足给定pattern的所有key |
dbsize | 返回当前数据库中key的数目 |
flushdb | 删除当前选择数据库中的所有key |
flushall | 删除所有数据库中的所有key |
redis的 Java 客户端简介
与 Shell 客户端支持单机与集群同一接口不同,Java 客户端针对单机环境与集群环境有不一样的接口(单机环境使用 Jedis对象,集群环境使用 JedisCluster 对象),本文针对单机环境进行介绍,集群环境的话,除了配置下主机地址与端口号,其他的接口操作同 Jedis 是一样的。
下面对 redis 提供的 Java 客户端接口进行介绍,由于代码中都有相应的注释,所以,不做详细描述:
- 公共接口
private static Jedis jedis;
private static final String PREFIX = "qinyi-";
private static final String HOST_IP = "127.0.0.1";
private static final int HOST_PORT = 6379;
private static final Logger logger = LoggerFactory.getLogger(RedisClient.class);
public synchronized static Jedis getJedis(String host_ip, int host_port) {
jedis = new Jedis(host_ip, host_port);
//jedis.auth("root"); //开启密码验证(配置文件中为 requirepass root)的时候需要执行该方法
return jedis;
}
public synchronized static Jedis getDefaultJedis() {
return getJedis(HOST_IP, HOST_PORT);
}
/**
* 清空 redis 中的所有数据
* */
public String flushRedis() {
logger.debug("flush redis data");
return getDefaultJedis().flushDB();
}
/**
* 根据 pattern 获取 redis 中的键
* */
public Set<String> getKeysByPattern(String pattern) {
return getDefaultJedis().keys(pattern);
}
/**
* 获取 redis 中所有的键
* */
public Set<String> getAllKeys() {
return getKeysByPattern("*");
}
/**
* 判断key是否存在redis中
* */
public boolean exists(String key) throws Exception {
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
return getDefaultJedis().exists(PREFIX + key);
}
/**
* 从Redis中移除一个key
* */
public void removeKey(String key) throws Exception {
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
getDefaultJedis().del(PREFIX + key);
}
- String类型接口
/**
* 存储字符串
* */
public void setString(String key, String value, int expireTime) throws Exception {
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
String finalKey = PREFIX + key;
getDefaultJedis().set(finalKey, value);
if (expireTime > 0) {
/**
* 如果设置了 expireTime, 那么这个 finalKey会在expireTime秒后过期,那么该键会被自动删除
* 这一功能配合出色的性能让Redis可以作为缓存系统来使用,成为了缓存系统Memcached的有力竞争者
* */
getDefaultJedis().expire(finalKey, expireTime);
}
}
/**
* 获取字符串
* */
public String getString(String key) throws Exception{
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
return getDefaultJedis().get(PREFIX + key);
}
- List类型接口
/**
* 存储 List
* */
public void pushList(String key, String value, String flag) throws Exception {
if (StringUtil.IsEmpty(key) || StringUtil.IsEmpty(flag)) {
logger.error("key or flag is null");
throw new Exception("key or flag is null");
}
/**
* key代表的是链表的名字
* List是一个双端链表,lpush是往链表的头部插入一条数据,rpush是往尾部插入一条数据
* */
if (flag.equalsIgnoreCase("L")) {
getDefaultJedis().lpush(PREFIX + key, value);
} else if (flag.equalsIgnoreCase("R")) {
getDefaultJedis().rpush(PREFIX + key, value);
} else {
logger.error("unknown flag");
throw new Exception("unknown flag");
}
}
/**
* 获取 List 中的单个元素
* */
public String popList(String key, String flag) throws Exception {
if (StringUtil.IsEmpty(key) || StringUtil.IsEmpty(flag)) {
logger.error("key or flag is null");
throw new Exception("key or flag is null");
}
if (flag.equalsIgnoreCase("L")) {
return getDefaultJedis().lpop(PREFIX + key);
} else if (flag.equalsIgnoreCase("R")) {
return getDefaultJedis().rpop(PREFIX + key);
} else {
logger.error("unknown flag");
throw new Exception("unknown flag");
}
}
/**
* 获取 List 中指定区间上的元素
* */
public List<String> getAppointedList(String key, long start, long end) throws Exception {
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
return getDefaultJedis().lrange(PREFIX + key, start, end);
}
/**
* 获取 List 上所有的元素
* */
public List<String> getList(String key) throws Exception {
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
return getDefaultJedis().lrange(PREFIX + key, 0, -1);
}
/**
* 获取 List 的长度
* */
public long getListLength(String key) throws Exception {
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
return getDefaultJedis().llen(PREFIX + key);
}
- Set类型接口
/**
* 存储 Set : 单值存储
* */
public void addValueToSet(String key, String value) throws Exception {
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
getDefaultJedis().sadd(PREFIX + key, value);
}
/**
* 存储 Set : 多值存储
* */
public void addListToSet(String key, List<String> values) throws Exception {
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
for (String value : values) {
getDefaultJedis().sadd(PREFIX + key, value);
}
}
/**
* 删除 Set 中的某个元素
* */
public void deleteElementInSet(String key, String value) throws Exception {
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
getDefaultJedis().srem(PREFIX + key, value);
}
/**
* 获取 Set 中所有的成员
* */
public Set<String> getSet(String key) throws Exception {
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
return getDefaultJedis().smembers(PREFIX + key);
}
/**
* 判断 value 是否属于 set
* */
public boolean isExistInSet(String key, String value) throws Exception {
if (StringUtil.IsEmpty(key) || StringUtil.IsEmpty(value)) {
logger.error("key or value is null");
throw new Exception("key or value is null");
}
return getDefaultJedis().sismember(PREFIX + key, value);
}
/**
* 获取 Set 中元素个数
* */
public long getLengthOfSet(String key) throws Exception {
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
return getDefaultJedis().scard(PREFIX + key);
}
/**
* 取两个 Set 的交集
* */
public Set<String> getSetInter(String key1, String key2) throws Exception {
if (StringUtil.IsEmpty(key1) || StringUtil.IsEmpty(key2)) {
logger.error("key1 or key2 is null");
throw new Exception("key1 or key2 is null");
}
return getDefaultJedis().sinter(PREFIX + key1, PREFIX + key2);
}
/**
* 取两个 Set 的并集
* */
public Set<String> getSetUnion(String key1, String key2) throws Exception {
if (StringUtil.IsEmpty(key1) || StringUtil.IsEmpty(key2)) {
logger.error("key1 or key2 is null");
throw new Exception("key1 or key2 is null");
}
return getDefaultJedis().sunion(PREFIX + key1, PREFIX + key2);
}
/**
* 取两个 Set 的差集
* */
public Set<String> getSetDiff(String key1, String key2) throws Exception {
if (StringUtil.IsEmpty(key1) || StringUtil.IsEmpty(key2)) {
logger.error("key1 or key2 is null");
throw new Exception("key1 or key2 is null");
}
return getDefaultJedis().sdiff(PREFIX + key1, PREFIX + key2);
}
- SortedSet类型接口
/**
* 存储有序集合 SortedSet
* */
public void setSortedSet(String key, double weight, String value) throws Exception {
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
getDefaultJedis().zadd(PREFIX + key, weight, value);
}
/**
* 获取有序集合指定区间上的元素
* */
public Set<String> getAppointedSortedSet(String key, long start, long end) throws Exception {
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
return getDefaultJedis().zrange(PREFIX + key, start, end);
}
/**
* 获取有序集合上的所有元素
* */
public Set<String> getSortedSet(String key) throws Exception {
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
return getDefaultJedis().zrange(PREFIX + key, 0, -1);
}
/**
* 获取有序集合上某个权重区间上的元素
* */
public long getLengthOfSortedSetByWeight(String key, double min, double max) throws Exception {
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
return getDefaultJedis().zcount(PREFIX + key, min, max);
}
/**
* 删除有序集合上的元素
* */
public void deleteElementInSortedSet(String key, String value) throws Exception {
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
getDefaultJedis().zrem(PREFIX + key, value);
}
/**
* 获取有序集合中元素的个数
* */
public long getLengthOfSortedSet(String key) throws Exception {
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
return getDefaultJedis().zcard(PREFIX + key);
}
/**
* 查看有序集合中元素的权重
* */
public double getWeight(String key, String value) throws Exception {
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
return getDefaultJedis().zscore(PREFIX + key, value);
}
- Hash类型接口
/**
* 存储 HashMap
* */
public void setHashMapByFieldAndValue(String key, String field, String value) throws Exception {
if (StringUtil.IsEmpty(key) || StringUtil.IsEmpty(field)) {
logger.error("key or field is null");
throw new Exception("key or field is null");
}
getDefaultJedis().hset(PREFIX + key, field, value);
}
/**
* 存储 HashMap
* */
public void setHashMapByMap(String key, Map<String, String> map) throws Exception {
if (StringUtil.IsEmpty(key) || map == null) {
logger.error("key or map is null");
throw new Exception("key or map is null");
}
getDefaultJedis().hmset(PREFIX + key, map);
}
/**
* 删除 HashMap 中的键值对
* */
public void deleteHashMapValueByField(String key, String field) throws Exception {
if (StringUtil.IsEmpty(key) || StringUtil.IsEmpty(field)) {
logger.error("key or field is null");
throw new Exception("key or field is null");
}
getDefaultJedis().hdel(PREFIX + key, field);
}
/**
* 获取 HashMap 中键对应的值
* */
public String getHashMapValueByField(String key, String field) throws Exception {
if (StringUtil.IsEmpty(key) || StringUtil.IsEmpty(field)) {
logger.error("key or field is null");
throw new Exception("key or field is null");
}
return getDefaultJedis().hget(PREFIX + key, field);
}
/**
* 获取 HashMap 中所有的 key
* */
public Set<String> getHashMapKeys(String key) throws Exception {
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
return getDefaultJedis().hkeys(PREFIX + key);
}
/**
* 获取 HashMap 中所有的值
* */
public List<String> getHashMapValues(String key) throws Exception {
if (StringUtil.IsEmpty(key)) {
logger.error("key is null");
throw new Exception("key is null");
}
return getDefaultJedis().hvals(PREFIX + key);
}
/**
* 判断 HashMap 中是否存在某一个键
* */
public boolean isFieldExistsInHashMap(String key, String field) throws Exception {
if (StringUtil.IsEmpty(key) || StringUtil.IsEmpty(field)) {
logger.error("key or field is null");
throw new Exception("key or field is null");
}
return getDefaultJedis().hexists(PREFIX + key, field);
}
相对关系型数据库而言,redis 以一种非常简单的思想来存储数据,由于它将数据存储在内存中,所以,读写非常高效,同时,它将内存中的数据写入数据库中,保证数据不会丢失,每次关闭并重新打开时,再将存储在本地数据库中的键值对信息载入内存。
redis 同时提供 Windows 和 Linux 系统的不同版本,针对不同的流行语言都有相应的 API 接口(目前来看, Java 最为活跃),方便了开发过程中的使用。
一些经典的数据库操作,redis 中都有很好的支持,比如保证一致性的事务,减小构建数据库开销的连接池接口(JedisPool)等等。
总的来说,使用 redis,你会感受到它的简洁与高效!
版权声明:本文为博主原创文章,未经博主允许不得转载。