Redis介绍 && Java客户端操作Redis

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 getKeysByPattern(String pattern) {
        return getDefaultJedis().keys(pattern);
    }

    /**
     *  获取 redis 中所有的键
     * */
    public Set 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 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 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 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 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 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 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 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 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 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 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 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 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,你会感受到它的简洁与高效!

你可能感兴趣的:(XM)