Jedi连接池

会有一股神秘感。 提交于 2019-12-03 07:04:23

简介

jedis用于创建和管理连接,并提供了对redis数据库的操作方法。Jedis相当于JDBC中的Connection,JedisPool相当于DBCP或者C3P0,而JedisCluster更像是Spring中的JDBCTemplate(将连接池和连接都给封装起来了,只提供给我们直接操作redis的api)。

JedisPool和JedisCluster在构造连接池对象的时候,需要传入JedisPoolConfig,host,port等。这些配置信息我们可以统一地定义在jedis.properties文件中,方便后续维护。但jedis有个不足,就是不能读取properties文件,需要我们手动取值设置。

使用例子

需求

使用jedis连接池对redis进行String、Set、Sorted Set、List、Hash和Key的操作。(这里仅测试单机版,集群不涉及)

工程环境

JDK:1.8.0_201
 maven:3.6.1
 IDE:Spring Tool Suites4 for Eclipse
 redis:3.2.100(windows64)

主要步骤

  1. 读取jedis.properties文件,创建并设置JedisPoolConfig;
  2. 根据配置参数构造JedisPool;
  3. 调用JedisPool的getResource方法获取Jedis对象;
  4. 使用Jedis进行CRUD操作。

创建项目

项目类型Maven Project,打包方式jar

引入依赖

<dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
</dependency>
<!-- jedis -->
<dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.9.3</version>
</dependency>

编写jedis.properties

路径:resources目录下

#############基本参数#############

#ip地址

redis.host=127.0.0.1

#端口号

redis.port=6379

#如果有密码

redis.password=root

#客户端超时时间单位是毫秒 默认是2000

redis.timeout=3000

#############资源数控制参数#############

#资源池的最大连接数。默认值8

redis.pool.maxTotal=8

#资源池允许最大空闲连接数。默认值8。建议=maxTotal

redis.pool.maxIdle=8

#资源池确保最少空闲连接数。默认0。

redis.pool.minIdle=0

#是否开启jmx监控,可用于监控。默认true。建议开启

redis.pool.jmxEnabled=true

#############借还参数#############

#当资源池用尽后,调用者是否要等待。默认值为true。建议默认。只有当为true时,下面的maxWaitMillis才会生效。

redis.pool.blockWhenExhausted=true

#当资源池连接用尽后,调用者的最大等待时间(单位毫秒)。默认-1:表示永不超时。不建议使用默认值。

redis.pool.maxWaitMillis=3000

#向资源池借用连接时是否做连接有效性检查(ping),无效连接会被移除。默认false。业务量很大时候建议false。

redis.pool.testOnBorrow=true

#向资源池归还连接时是否做连接有效性测试(ping),无效连接会被移除。默认false。业务量很大时候建议false。

redis.pool.testOnReturn=false

#############空闲资源监控#############

#是否开启空闲资源监测。默认false。建议true。

redis.pool.testWhileIdle=true

#空闲资源的检测周期(单位为毫秒)。默认-1:不检测。建议设置,周期自行选择。

redis.pool.timeBetweenEvictionRunsMillis=30000

#资源池中资源最小空闲时间(单位为毫秒),达到此值后空闲资源将被移除。

#默认值1000*60*30 = 30分钟。建议默认,或根据自身业务选择。

redis.pool.minEvictableIdleTimeMillis=300000

#做空闲资源检测时,每次的采样数。默认3。

#可根据自身应用连接数进行微调,如果设置为-1,就是对所有连接做空闲监测。

redis.pool.numTestsPerEvictionRun=3

编写JedisUtils

这个工具类的主要作用是加载配置文件、初始化连接池、获取连接等。

路径:cn.sdd.jedis

/**
 * @ClassName: JedisUtils
 * @Description: jedis工具类,用于获取连接
 * @author: sdd
 * @date: 2018年9月1日 下午8:47:26
 */
public class JedisUtils {
        private static ThreadLocal<Jedis> tl = new ThreadLocal<Jedis>();
        private static Object obj = new Object();
        //连接池对象
        private static JedisPool jedisPool;
        
        static {
                init();
        }
        /**
         * @Title: getJedis
         * @Description: 获取连接对象的方法,线程安全
         * @author: sdd
         * @date: 2019年8月31日 下午9:22:29
         * @return: Jedis
         */
        public static Jedis getJedis() throws Exception{
                //从当前线程中获取连接对象
                Jedis jedis = tl.get();
                //判断为空的话,创建连接并绑定到当前线程
                if(jedis == null) {
                         synchronized (obj) {
                                  if(tl.get() == null) {
                                           jedis = jedisPool.getResource();
                                           tl.set(jedis);
                                  }
                         }
                }
                return jedis;
        }
        /**
         * @Title: returnJedis
         * @Description: 交还jedis,校验如果jedis失效就将其移出
         * @author: sdd
         * @date: 2018年9月1日 下午9:13:57
         * @return: void
         */
        public static void returnJedis() {
                Jedis jedis = tl.get();
                if(jedis!=null) {
                         if(!jedis.isConnected()) {
                                  tl.remove();
                                  jedis.close();
                         }
                }
        }
        
        /**
         * @Title: init
         * @Description: 加载配置文件,并初始化jedisPool
         * @author: sdd
         * @date: 2018年9月1日 下午8:48:39
         * @return: void
         */
        private static void init() {
                //加载配置文件
                InputStream in = JedisUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
                Properties properties = new Properties();
                try {
                         properties.load(in);
                } catch (IOException e) {
                         System.err.println("加载配置文件失败,创建连接池失败");
                         e.printStackTrace();
                         return;
                }
                //设置配置对象
                JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
           jedisPoolConfig.setMaxTotal(Integer.parseInt(properties.getProperty("redis.pool.maxTotal")));
             jedisPoolConfig.setMaxIdle(Integer.parseInt(properties.getProperty("redis.pool.maxIdle")));
             jedisPoolConfig.setMinIdle(Integer.parseInt(properties.getProperty("redis.pool.minIdle")));
         jedisPoolConfig.setMaxWaitMillis(Integer.parseInt(properties.getProperty("redis.pool.maxWaitMillis")));
         jedisPoolConfig.setTestOnBorrow(Boolean.parseBoolean(properties.getProperty("redis.pool.testOnBorrow")));
         jedisPoolConfig.setTestOnReturn(Boolean.parseBoolean(properties.getProperty("redis.pool.testOnReturn")));
                //创建jedis连接池
                jedisPool = new JedisPool(jedisPoolConfig,
                                  properties.getProperty("redis.host"),
                                  Integer.parseInt(properties.getProperty("redis.port")),
                                  Integer.parseInt(properties.getProperty("redis.timeout")),
                                  properties.getProperty("redis.password")
                                  );
        }
}

编写测试类

路径:test目录下的cn.sdd.jedis,分别测试操作String、Set、Sorted Set、List、Hash和Key。

测试String

/**
 * @Title: testKey
 * @Description: 测试操作String的方法
 * @author: sdd
 * @date: 2018年9月1日 下午9:30:43
 * @return: void
 * @throws Exception 
 */
@Test
public void testString() throws Exception {
        //获取Jedis对象
        Jedis jedis = JedisUtils.getJedis();
        String key = "jedis-demo:testString";
        //添加键值对
        jedis.set(key, "test001");
        //获取键值对
        System.out.println(jedis.get(key));
        //删除键值对
        jedis.del(key);
        //判断键值对是否存在
        System.out.println(jedis.exists(key));
        //归还连接
        JedisUtils.returnJedis();
}

测试List

注意:list类型的本质是双向链表,jedis提供的api中不支持通过指定value来更新和删除元素。另外list的第一位是从0开始,而-1表示最后一位,-2表示倒数第二位。

/**
 * @Title: testList
 * @Description: 测试操作List的方法
 * @author: sdd
 * @date: 2018年9月1日 下午9:30:43
 * @return: void
 * @throws Exception 
 */
@Test
public void testList() throws Exception {
        //获取Jedis对象
        Jedis jedis = JedisUtils.getJedis();
        String key = "jedis-demo:testlist5";
        //添加元素
        jedis.lpush(key, "test001","test002","test003","test004");
        //修改元素:只能根据索引删除
        jedis.lset(key, 0, "testList001");
        //删除第一个元素:只能删除第一个或最后一个
        jedis.lpop(key);
        //遍历元素
        List<String> list = jedis.lrange(key, 0, -1);
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()) {
                System.out.println(iterator.next());
        }
        //归还连接
        JedisUtils.returnJedis();
}

测试Set

注意:set的本质是哈希表,元素是唯一的,jedis提供的api中并不支持按索引或值更新元素。

/**
 * @Title: testSet
 * @Description: 测试操作Set的方法
 * @author: sdd
 * @date: 2018年9月1日 下午9:30:43
 * @return: void
 * @throws Exception 
 */
@Test
public void testSet() throws Exception {
        //获取Jedis对象
        Jedis jedis = JedisUtils.getJedis();
        String key = "jedis-demo:testSet";
        //添加元素
        jedis.sadd(key, "test001","test002","test004","test003");
        //更新元素:不能更新元素
        //删除元素
        jedis.srem(key, "test001");
        //判断元素是否存在
        System.out.println(jedis.sismember(key, "test001"));
        //遍历元素
        Set<String> smembers = jedis.smembers(key);
        Iterator<String> iterator = smembers.iterator();
        while(iterator.hasNext()) {
                System.out.println(iterator.next());
        }
        //归还连接
        JedisUtils.returnJedis();
}

测试Sorted Set

/**
 * @Title: testSortedSet
 * @Description: 测试操作Sorted Set的方法
 * @author: sdd
 * @date: 2018年9月1日 下午9:30:43
 * @return: void
 * @throws Exception 
 */
@Test
public void testSortedSet() throws Exception {
        //获取Jedis对象
        Jedis jedis = JedisUtils.getJedis();
        String key = "jedis-demo:testSortedSet";
        //添加元素
        jedis.zadd(key, 1D, "test001");
        jedis.zadd(key, 2D, "test002");
        jedis.zadd(key, 4D, "test004");
        jedis.zadd(key, 3D, "test003");
        //更新元素
        jedis.zadd(key, 5D, "test001");
        //删除元素
        jedis.zrem(key, "test002");
        //查找指定元素的score
        System.out.println(jedis.zscore(key,"test003"));
        //查找指定指定元素的排名
        System.out.println(jedis.zrank(key,"test003"));
        //遍历元素
        Set<String> smembers = jedis.zrange(key, 0, -1);
        Iterator<String> iterator = smembers.iterator();
        while(iterator.hasNext()) {
                System.out.println(iterator.next());
        }
        //归还连接
        JedisUtils.returnJedis();
}

测试Hash

/**
 * @Title: testHash
 * @Description: 测试操作Hash的方法
 * @author: sdd
 * @date: 2018年9月1日 下午9:30:43
 * @return: void
 * @throws Exception 
 */
@Test
public void testHash() throws Exception {
        //获取Jedis对象
        Jedis jedis = JedisUtils.getJedis();
        String key = "jedis-demo:testHash";
        //添加元素
        jedis.hset(key, "id", "1");
        jedis.hset(key, "name", "zzs");
        jedis.hset(key, "age", "18");
        jedis.hset(key, "address", "北京");
        //更新元素
        jedis.hset(key, "age", "19");
        //删除元素
        jedis.hdel(key, "id");
        //获取指定元素的值
        System.out.println(jedis.hget(key, "address"));
        //遍历元素
        Map<String, String> map = jedis.hgetAll(key);
        for(Entry<String, String> entry : map.entrySet()) {
                System.out.println(entry.getKey()+"="+entry.getValue());
        }
        //归还连接
        JedisUtils.returnJedis();
}

测试Key

/**
 * @Title: testKey
 * @Description: 测试操作key的方法
 * @author: sdd
 * @date: 2018年9月1日 下午9:30:43
 * @return: void
 * @throws Exception 
 */
@Test
public void testKey() throws Exception {
        //获取Jedis对象
        Jedis jedis = JedisUtils.getJedis();
        String key = "jedis-demo:testKey";
        //添加键值对
        jedis.set(key, "test001");
        //设置key的过期时间
        jedis.expire(key, 5);
        Thread.sleep(3000);
        //查询key的剩余时间
        System.out.println(jedis.ttl(key));
        //清除key的过期时间
        jedis.persist(key);
        System.out.println(jedis.ttl(key));
        //归还连接
        JedisUtils.returnJedis();
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!