Redis的java客户端Jedis的使用

Redis的java客户端Jedis的使用

标签(空格分隔): 未分类


一、Jedis简介和使用

使用Jedis提供的JavaAPI对Redis进行操作,是Redis官方推崇的方式;并且,使用Jedis提供的对Redis的支持也最为灵活、全面;不足之处,就是编码复杂度较高。

  • 入门使用:

下载Jedis的依赖包jedis-2.1.0.jar,然后将其添加到classpath下面。然后,即可进行编程。
定义连接:Redis暂时不要设置登录密码
Jedis jedis = new Jedis("192.168.142.12");
进行键值存储:
jedis.set("country", "China");
获取value值:
String country = jedis.get("country");
删除key:
jedis.del("country");

  • 使用连接池:

添加依赖包commons-pool.jar,注意不要选择高版本,以免不必要的错误。
配置属性文件:redis.properties

redis.host=192.168.142.12       #Redis服务器地址  
redis.port=6379                 #服务端口  
redis.timeout=3000              #超时时间:单位ms  
redis.password=nick123          #授权密码  

redis.pool.maxActive=200        #最大连接数:能够同时建立的“最大链接个数”  
redis.pool.maxIdle=20           #最大空闲数:空闲链接数大于maxIdle时,将进行回收  
redis.pool.minIdle=5            #最小空闲数:低于minIdle时,将创建新的链接  
redis.pool.maxWait=3000         #最大等待时间:单位ms  

redis.pool.testOnBorrow=true    #使用连接时,检测连接是否成功  
redis.pool.testOnReturn=true    #返回连接时,检测连接是否成功  

加载属性文件:redis.properties
ResourceBundle bundle = ResourceBundle.getBundle("redis");
创建配置对象:

JedisPoolConfig config = new JedisPoolConfig();  
String host = bundle.getString("redis.host");  
...  
config.setMaxActive(Integer.valueOf(bundle.getString("redis.pool.maxActive")));  
...  
config.setTestOnBorrow(Boolean.valueOf(bundle.getString("redis.pool.testOnBorrow")));  
...  

创建Jedis连接池:

JedisPool pool = new JedisPool(config, host, port, timeout, password);  
  • 使用方式:

从连接池获取Jedis对象:
Jedis jedis = pool.getResource();
基本操作:

jedis.set("province", "shannxi");  
String province = jedis.get("province");  
jedis.del("province");  

将Jedis对象归还给连接池:
pool.returnResource(jedis);

二、Jedis使用详解

  • jedis简单测试
package com.kang.redis;

import redis.clients.jedis.Jedis;

public class JedisDemo {

    public static void main(String[] args) {
        // 构造jedis对象
        Jedis jedis = new Jedis("127.0.0.1", 6379);
        // 向redis中添加数据
        jedis.set("mytest", "123");
        // 从redis中读取数据
        String value = jedis.get("mytest");

        System.out.println(value);
        // 关闭连接
        jedis.close();

    }

}
  • jedis连接池测试
package com.kang.redis;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class JedisPoolDemo {
   

    public static void main(String[] args) {
        // 构建连接池配置信息
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        // 设置最大连接数
        jedisPoolConfig.setMaxTotal(50);

        // 构建连接池
        JedisPool jedisPool = new JedisPool(jedisPoolConfig, "127.0.0.1", 6379);

        // 从连接池中获取连接
        Jedis jedis = jedisPool.getResource();

        // 读取数据
        System.out.println(jedis.get("mytest"));

        // 将连接还回到连接池中
        jedisPool.returnResource(jedis);

        // 释放连接池
        jedisPool.close();

    }

}
  • jedis设置集群连接池
package com.kang.redis;

import java.util.ArrayList;
import java.util.List;

import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;

/**
 * 集群式的连接池
 * 
 */
public class ShardedJedisPoolDemo {
   

    public static void main(String[] args) {
        // 构建连接池配置信息
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        // 设置最大连接数
        poolConfig.setMaxTotal(50);

        // 定义集群信息
        List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
        shards.add(new JedisShardInfo("127.0.0.1", 6379));
        //可以加入其他集群的jedis端口
        // 定义集群连接池
        ShardedJedisPool shardedJedisPool = new ShardedJedisPool(poolConfig, shards);
        ShardedJedis shardedJedis = null;
        try {
            // 从连接池中获取到jedis分片对象
            shardedJedis = shardedJedisPool.getResource();

            // 从redis中获取数据
            String value = shardedJedis.get("mytest");
            System.out.println(value);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != shardedJedis) {
                // 关闭,检测连接是否有效,有效则放回到连接池中,无效则重置状态
                shardedJedis.close();
            }
        }

        // 关闭连接池
        shardedJedisPool.close();

    }
}
  • 一个jedis的工具类
package com.kang.redis;  

import java.util.HashMap;  
import java.util.Map;  

import org.slf4j.Logger;  
import org.slf4j.LoggerFactory;  

import redis.clients.jedis.Jedis;  
import redis.clients.jedis.JedisPool;  
import redis.clients.jedis.JedisPoolConfig;  

public class RedisUtil  {
     
    protected Logger log = LoggerFactory.getLogger(getClass());  

    /** 
     * 私有构造器. 
     */  
    private RedisUtil() {  

    }  
    private static Map<String,JedisPool> maps  = new HashMap<String,JedisPool>();  


    /** 
     * 获取连接池. 
     * @return 连接池实例 
     */  
    static JedisPool getPool(String ip,int port) {  
        String key = ip+":" +port;  
        JedisPool pool = null;  
        if(!maps.containsKey(key)) {  
            JedisPoolConfig config = new JedisPoolConfig();  
            config.setTestOnBorrow(true);  
            config.setTestOnReturn(true);  
            try{    
                /** 
                 *如果你遇到 java.net.SocketTimeoutException: Read timed out exception的异常信息 
                 *请尝试在构造JedisPool的时候设置自己的超时值. JedisPool默认的超时时间是2秒(单位毫秒) 
                 */  
                pool = new JedisPool(config, ip, port);  
                maps.put(key, pool);  
            } catch(Exception e) {  
                e.printStackTrace();  
            }  
        }else{  
            pool = maps.get(key);  
        }  
        return pool;  
    }  

    /** 
     *类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例 
     *没有绑定关系,而且只有被调用到时才会装载,从而实现了延迟加载。 
     */  
    private static class RedisUtilHolder{
     
        /** 
         * 静态初始化器,由JVM来保证线程安全 
         */  
        private static RedisUtil instance = new RedisUtil();  
    }  

    /** 
     *当getInstance方法第一次被调用的时候,它第一次读取 
     *RedisUtilHolder.instance,导致RedisUtilHolder类得到初始化;而这个类在装载并被初始化的时候,会初始化它的静 
     *态域,从而创建RedisUtil的实例,由于是静态的域,因此只会在虚拟机装载类的时候初始化一次,并由虚拟机来保证它的线程安全性。 
     *这个模式的优势在于,getInstance方法并没有被同步,并且只是执行一个域的访问,因此延迟初始化并没有增加任何访问成本。 
     */  
    public static RedisUtil getInstance() {  
        return RedisUtilHolder.instance;  
    }  

    /** 
     * 获取Redis实例. 
     * @return Redis工具类实例 
     */  
    public static Jedis getJedis(String ip,int port) {  
        Jedis jedis  = null;  
        int count =0;  
        do{  
            try{   
                jedis = getPool(ip,port).getResource();  
                //log.info("get redis master1!");  
            } catch (Exception e) {  
                 // 销毁对象    
                getPool(ip,port).returnBrokenResource(jedis);    
            }  
            count++;  
        }while(jedis==null&&count<1000);  
        return jedis;  
    }  

    /** 
     * 释放redis实例到连接池. 
     * @param jedis redis实例 
     */  
    public static void closeJedis(Jedis jedis,String ip,int port) {  
        if(jedis != null) {  
            getPool(ip,port).returnResource(jedis);  
        }  
    }  
}  
  • 一个jedis的详细测试代码
package com.kang.redis;  

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.junit.Test;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.SortingParams;


public class TestCase {  

    /** 
     * 在不同的线程中使用相同的Jedis实例会发生奇怪的错误。但是创建太多的实现也不好因为这意味着会建立很多sokcet连接, 
     * 也会导致奇怪的错误发生。单一Jedis实例不是线程安全的。为了避免这些问题,可以使用JedisPool, 
     * JedisPool是一个线程安全的网络连接池。可以用JedisPool创建一些可靠Jedis实例,可以从池中拿到Jedis的实例。 
     * 这种方式可以解决那些问题并且会实现高效的性能 
     */  


    @Test
    public void Hello() {  
        Jedis jedis = RedisUtil.getJedis("127.0.0.1",6379);  
        try {  
            // 向key-->name中放入了value-->java  
            jedis.set("name", "java");  
            String ss = jedis.get("name");  
            System.out.println(ss);  

            // 很直观,将spring append到已经有的value之后  
            jedis.append("name", "spring");  
            ss = jedis.get("name");  
            System.out.println(ss);  //输出javasspring

            // 2、直接覆盖原来的数据  
            jedis.set("name", "spring");  
            System.out.println(jedis.get("name"));  //输出spring

            // 删除key对应的记录  
            jedis.del("name");  
            System.out.println(jedis.get("name"));// 执行结果:null  

            /** 
             * mset相当于 jedis.set("name","java"); jedis.set("jarorwar","aaa"); 
             */  
            jedis.mset("name", "java", "jarorwar", "aaa");  
            System.out.println(jedis.mget("name", "jarorwar"));  //输出[java, aaa]
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            RedisUtil.getPool("127.0.0.1",6379).returnResource(jedis);  
        }  

    }  

    @Test
    public void testKey() {  
        Jedis jedis = RedisUtil.getJedis("127.0.0.1",6379);  
        System.out.println("=============key==========================");  
        // 清空数据  
        System.out.println(jedis.flushDB());  
        System.out.println(jedis.echo("foo"));  //Echo命令用于打印给定的字符串。
        // 判断key否存在  
        System.out.println(jedis.exists("foo"));  //false
        jedis.set("key", "values");  
        System.out.println(jedis.exists("key"));  //true
    }  

    @Test
    public  void testString() {  
        System.out.println("==String==");  
        Jedis jedis = RedisUtil.getJedis("127.0.0.1",6379);  
        try {  
            // String  
            jedis.set("key", "Hello World!");  
            String value = jedis.get("key");  
            System.out.println(value);  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            RedisUtil.getPool("127.0.0.1",6379).returnResource(jedis);  
        }  

        System.out.println("=============String==========================");  
        // 清空数据  
        System.out.println(jedis.flushDB());  
        // 存储数据  
        jedis.set("foo", "bar");  
        System.out.println(jedis.get("foo"));  
        // 若key不存在,则存储  
        jedis.setnx("foo", "foo not exits");  //因为key(foo)已存在,所以这里不会存储这个值
        System.out.println(jedis.get("foo"));  //输出foo
        // 覆盖数据  
        jedis.set("foo", "foo update");  
        System.out.println(jedis.get("foo"));  //foo update
        // 追加数据  
        jedis.append("foo", " hello, world");  
        System.out.println(jedis.get("foo"));  //foo update hello, world
        // 设置key的有效期,并存储数据  
        jedis.setex("foo", 2, "foo not exits");  //有效期两秒
        System.out.println(jedis.get("foo"));  //foo not exits
        try {  
            Thread.sleep(3000);  //延时3秒,数据失效
        } catch (InterruptedException e) {  
        }  
        System.out.println(jedis.get("foo"));  //null
        // 获取并更改数据  
        jedis.set("foo", "foo update");  
        System.out.println(jedis.getSet("foo", "foo modify"));  //foo modify
        System.out.println(jedis.get("foo"));//foo modify
        // 截取value的值  
        System.out.println(jedis.getrange("foo", 1, 5));  //oo mo
        System.out.println(jedis.mset("mset1", "mvalue1", "mset2", "mvalue2",  
                "mset3", "mvalue3", "mset4", "mvalue4"));  
        System.out.println(jedis.mget("mset1", "mset2", "mset3", "mset4")); //[mvalue1, mvalue2, mvalue3, mvalue4] 
        System.out.println(jedis.del(new String[] { "foo", "foo1", "foo3" }));  //输出1,DEL命令用于删除已存在的键。不存在的 key 会被忽略。
        //返回值是被删除 key 的数量。
    }  

    @Test
    public void testList() {  
        System.out.println("==List==");  
        Jedis jedis = RedisUtil.getJedis("127.0.0.1",6379);  
        try {  
            // 开始前,先移除所有的内容  
            jedis.del("messages");  
            jedis.rpush("messages", "Hello how are you?");  
            jedis.rpush("messages", "Fine thanks. I'm having fun with redis.");  
            jedis.rpush("messages", "I should look into this NOSQL thing ASAP");  

            // 再取出所有数据。jedis.lrange是按范围取出,  
            // 第一个是key,第二个是起始位置,第三个是结束位置,jedis.llen获取长度 -1表示取得所有  
            List<String> values = jedis.lrange("messages", 0, -1);  
            System.out.println(values);  

        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            RedisUtil.getPool("127.0.0.1",6379).returnResource(jedis);  
        }  

        // 清空数据  
        System.out.println(jedis.flushDB());  
        // 添加数据  
        jedis.lpush("lists", "8");  
        jedis.lpush("lists", "5");  
        jedis.lpush("lists", "9");  
        // 数组长度  
        System.out.println(jedis.llen("lists"));  //3
        // 排序  
        System.out.println(jedis.sort("lists"));  //[5, 8, 9](默认升序排序)
        /*
         * 如果使用Redis SORT排序的不是数字,是字母,将他们按照字典的顺序排名,则需要使用 SORT key ALPHA
         * 如果不加ALPHA参数,则会报错,提示:(error) ERR One or more scores can't be converted into double。
         * 我们还可以使用关系型数据库的DESC进行倒序排序和LIMIT offset count来限定获取的条数
         */
        // 字串  
        System.out.println(jedis.lrange("lists", 0, 3));  //[9, 5, 8]
        /*LRANGE命令将返回存储在key列表的特定元素。偏移量开始和停止是从0开始的索引,
         * 0是第一元素(该列表的头部),1是列表的下一个元素。这些偏移量也可以是表示开始在列表的末尾偏移负数。
         * 例如,-1是该列表的最后一个元素,-2倒数第二个,等等。
         */
        // 修改列表中单个值  
        jedis.lset("lists", 0, "hello list!");  
        System.out.println(jedis.lrange("lists", 0, 3));//[hello list!, 5, 8]
        // 获取列表指定下标的值  
        System.out.println(jedis.lindex("lists", 1));  //5
        // 删除列表指定下标的值  
        System.out.println(jedis.lrem("lists", 1, "vector"));  //输出0
        /*
         *  Lrem 根据参数 COUNT 的值,移除列表中与参数 VALUE 相等的元素。命令形式:LREM KEY_NAME COUNT VALUE
         *  COUNT 的值可以是以下几种:
         *  count > 0 : 从表头开始向表尾搜索,移除与 VALUE 相等的元素,数量为 COUNT 。
         *  count < 0 : 从表尾开始向表头搜索,移除与 VALUE 相等的元素,数量为 COUNT 的绝对值。
         *  count = 0 : 移除表中所有与 VALUE 相等的值。
         *  返回值是被移除元素的数量。 列表不存在时返回 0 。
         */
        // 删除区间以外的数据  
        System.out.println(jedis.ltrim("lists", 0, 1)); //ok 
        /*
         * Ltrim 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
         * 下标 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。 你也可以使用负数下标,
         * 以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。命令形式: LTRIM KEY_NAME START STOP
         * 返回值:命令执行成功时,返回 ok 。
         */
        // 列表出栈  
        System.out.println(jedis.lpop("lists"));  //hello list!
        /*
         *  Lpop 命令用于移除并返回列表的第一个元素。返回值:列表的第一个元素。 当列表 key 不存在时,返回 nil 。
         */
        // 整个列表值  
        System.out.println(jedis.lrange("lists", 0, -1)); // [5]
    }  

    @Test
    public  void testSet() {  
        System.out.println("==Set==");  
        Jedis jedis = RedisUtil.getJedis("127.0.0.1",6379);  
        try {  
            jedis.sadd("myset", "1");  
            jedis.sadd("myset", "2");  
            jedis.sadd("myset", "3");  
            jedis.sadd("myset", "4");  
            Set<String> setValues = jedis.smembers("myset");  // Smembers命令返回集合中的所有的成员。 不存在的集合 key 被视为空集合。
            System.out.println(setValues);  //输出是无序的[3, 2, 1, 4]

            // 移除noname  
            jedis.srem("myset", "4");  //Srem 命令用于移除集合中的一个或多个成员元素,不存在的成员元素会被忽略。当 key 不是集合类型,返回一个错误。
            System.out.println(jedis.smembers("myset"));// 获取所有加入的value,输出[3, 2, 1]
            System.out.println(jedis.sismember("myset", "4"));// 输出false。Sismember 命令判断成员元素是否是集合的成员。
            System.out.println(jedis.scard("myset"));// 返回集合的元素个数 :3
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            RedisUtil.getPool("127.0.0.1",6379).returnResource(jedis);  
        }  

        // 清空数据  
        System.out.println(jedis.flushDB());  
        // 添加数据  
        jedis.sadd("sets", "HashSet");  
        jedis.sadd("sets", "SortedSet");  
        jedis.sadd("sets", "TreeSet");  
        // 判断value是否在列表中  
        System.out.println(jedis.sismember("sets", "TreeSet")); //true 
        // 整个列表值  
        System.out.println(jedis.smembers("sets"));  //[SortedSet, TreeSet, HashSet]
        // 删除指定元素  
        System.out.println(jedis.srem("sets", "SortedSet"));  
        // 出栈  
        System.out.println(jedis.spop("sets"));  //Spop 命令用于移除并返回集合中的一个随机元素。
        System.out.println(jedis.smembers("sets"));  
        //  
        jedis.sadd("sets1", "HashSet1");  
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值