redis个人学习笔记 八:Redis的Java客户端Jedis简单使用

这篇博客是关于Redis的Java客户端Jedis的学习笔记,涵盖了Jedis所需jar包、常用操作如连通性测试、事务处理、主从复制,以及JedisPool的使用和配置详解,包括连接池管理、配置参数的意义和作用。
摘要由CSDN通过智能技术生成

       此文是我看尚硅谷教学视频后的个人的redis学习笔记,每一张截图都是我亲自敲后截图放在笔记中的,粘贴在博客上可能会有点点模糊,若有错误或不足,还望各位大神多多指正!

10 Redis的Java客户端Jedis简单使用

10.1 Jedis所需要的jar包

       ① commons-pool-1.6.jar
       ② jedis-2.1.0.jar
       ③ Pom依赖

<dependency>
   <groupId>redis.clients</groupId>
   <artifactId>jedis</artifactId>
   <version>2.1.0</version>
</dependency>
<dependency>
   <groupId>org.apache.commons</groupId>
   <artifactId>commons-lang3</artifactId>
   <version>3.3.2</version>
</dependency>

10.2 Jedis常用操作

10.2.1 测试连通性

/**
 * 测试是否连通
 */
public void connectTest(){
  //连接本地的Redis服务
    Jedis jedit=new Jedis("127.0.0.1",6379);
  //查看服务是否运行,打出pong表示OK
    System.out.println("连接返回的值为:"+jedit.ping());
}

10.2.1 5+1

package com.example.pay.payTest;

import redis.clients.jedis.BinaryClient;
import redis.clients.jedis.Jedis;

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

public class test {

    public static void main(String[] args) throws InterruptedException {
    //连接本地的Redis服务
        Jedis jedis=new Jedis("127.0.0.1",6379);
        test test=new test();
        //test.connectTest(jedis);
        //test.keyTest(jedis);
        //test.stringTest(jedis);
        //test.listTest(jedis);
        //test.setTest(jedis);
        //test.hashTest(jedis);
        test.zsetTest(jedis);
    }
    /**
     * 测试是否连通
     */
    public void connectTest(Jedis jedis){
      //查看服务是否运行,打出pong表示OK
        System.out.println("连接返回的值为:"+jedis.ping());
    }
    /**
     * key常用命令练习
     */
    public void keyTest(Jedis jedis) throws InterruptedException {
     //新增
        jedis.flushAll();
        jedis.set("k1","1");
        jedis.set("k2","2");
        jedis.set("k3","3");
     //查询所有的key
        Set<String> set=jedis.keys("*");
        Iterator iter = set.iterator();
        while (iter.hasNext()){
            System.out.println((String) iter.next());
        }
     //判断某个key是否存在
        System.out.println(jedis.exists("k2"));
     //把k2移动到3号库
        jedis.move("k2",2);
     //设定k3三秒过期
        jedis.expire("k3",10);
        Thread.sleep(5000);
     //查看k3还有多久过期
        System.out.println("k3还有"+jedis.ttl("k3")+"秒过期");
     //查看k1的数据类型
        System.out.println("k1的数据类型是:"+jedis.type("k1")  );
    }
    /**
     *String常用命令练习
     */
    public void stringTest(Jedis jedis) throws InterruptedException {
     //set:增
        jedis.flushAll();
        jedis.set("k1","1");
        jedis.set("k2","2");
        jedis.set("k3","3");
     //get:查
        System.out.println("k1的value:"+jedis.get("k1"));
     //del:删
        jedis.del("k3");
     //append:拼接
        jedis.append("k2","asdfqwer");
        System.out.println("新的k2的value:"+jedis.get("k2"));
     //strlen:获得指定key的长度
        System.out.println("k2的长度:"+jedis.strlen("k2"));
     //incr:每次+1
        for(int i=0;i<3;i++){
            jedis.incr("k1");
        }
        System.out.println("incr后k1的value:"+jedis.get("k1"));
     //incrBy:按指定数增长
        System.out.println("incrBy后k1的value:"+jedis.incrBy("k1",2));
     //decr:每次-1
        System.out.println("decr后k1的value:"+jedis.decr("k1"));
     //decrBy:按指定数减少
        System.out.println("decryBy后k1的value"+jedis.decrBy("k1",2));
     //getrange:得到区间范围的值
        jedis.set("k4","abcdefghijklmn");
        System.out.println("k4 0~2的值是:"+jedis.getrange("k4",0,2));
     //setrange:设置区间值
        jedis.setrange("k4",0,"000");
        System.out.println("设置了区间值后的K4的value:"+jedis.get("k4"));
     //setex:设置带过期时间得key
        jedis.setex("k5",1,"5");
        Thread.sleep(2000);
        long num=jedis.ttl("K5");
        if(num==-2){
            System.out.println("k5已经过期");
        }else{
            System.out.println("k5还有"+num+"秒过期");
        }
     //setnx:只有在 key 不存在时设置 key 的值。
        jedis.set("k6","6");
        long numm=jedis.setnx("k6","66");
        if(numm==0){
            System.out.println("k6已经存在了。");
        }
     //mset:同时设置一个或多个 key-value 对
        jedis.mset("k7","7","k8","8","k9","9","k10","10");
        Set<String> set=jedis.keys("*");
        Iterator iter = set.iterator();
        System.out.println("存在的key:");
        while (iter.hasNext()){
            System.out.print((String) iter.next()+" ");
        }
        System.out.println("");
     //mget:获取所有给定 key 的值。
        System.out.println("获取的k1,k2,k4的value分别是:"+jedis.mget("k1","k2","k4"));
     //getset:将给定 key 的值设为 value ,并返回 key 的旧值(old value)。
        System.out.println("k1旧的值是:"+jedis.getSet("k1","10"));
    }
    /**
     *  List常用命令练习
     */
    public void listTest(Jedis jedis){
      //lpush
        jedis.flushAll();
        jedis.lpush("k1","1","2","3","4","5");
        System.out.println("k1从左边push后的值:"+jedis.lrange("k1",0,-1));
      //rpush
        jedis.rpush("k2","1","2","3","4","5");
        System.out.println("k2从右边push后的值:"+jedis.lrange("k2",0,-1));
      //lpop
        System.out.println("k1栈顶出去的值:"+jedis.lpop("k1"));
      //rpop
        System.out.println("k2栈尾出去的值:"+jedis.rpop("k2"));
      //lindex:按照索引下标获得元素(从上到下)
        System.out.println("k1的值"+jedis.lrange("k1",0,-1));
        System.out.println("k1下标为1的值:"+jedis.lindex("k1",1));
      //llen:取长度
        System.out.println("k1的长度:"+jedis.llen("k1"));
      //lrem:删N个value
        jedis.rpush("k3","1","1","1","2","2","2","2","3","3","3");
        jedis.lrem("k3",2,"3");
        System.out.println("删除了2个3后的k3的值:"+jedis.lrange("k3",0,-1));
      //ltrim:截取指定范围的值后再赋值给key
        jedis.ltrim("k3",0,4);
        System.out.println("k3新的值为:"+jedis.lrange("k3",0,-1));
      //rpoplpush:把源列表最后一位弹出放到目标列表的第一位
        jedis.rpush("k4","a","a","b","b","c","c");
        jedis.rpoplpush("k3","k4");
        System.out.println("此时k3的值:"+jedis.lrange("k3",0,-1));
        System.out.println("此时k4的值:"+jedis.lrange("k4",0,-1));
      //lset:修改指定下标的值
        jedis.lset("k1",1,"h");
        System.out.println("修改指定下标后k1的值:"+jedis.lrange("k1",0,-1));
      //linsert:在指定值前插入数据
        jedis.linsert("k1",BinaryClient.LIST_POSITION.BEFORE,"2","java");
        System.out.println("修改后的k1的值:"+jedis.lrange("k1",0,-1));
    }
    /**
     * Set常用命令练习
     */
    public void setTest(Jedis jedis){
        jedis.flushAll();
     //sadd:增
        jedis.sadd("k1","1","2","3","4","5","1");//不会存入重复值
        System.out.println("k1的值为:"+jedis.smembers("k1"));
     //sismember:判断是否存在
        System.out.println("2是k1的值:"+jedis.sismember("k1","2"));
     //scard:获取集合里面的元素个数
        System.out.println("k1值的个数:"+jedis.scard("k1"));
     //srem:删除集合中元素
        jedis.srem("k1","1");
        System.out.println("删除掉1后的k1的值:"+jedis.smembers("k1"));
     //srandmember:随机出数
        System.out.println("k1随机出的值:"+jedis.srandmember("k1"));
     //spop:随机出栈
        System.out.println("k1随机出栈的是:"+jedis.spop("k1"));
     //smove key1  key2 在key1里某个值:将key1里的某个值赋给key2
        jedis.sadd("k2","a","b","c","d");
        jedis.smove("k1","k2","2");
        System.out.println("k1的值:"+jedis.smembers("k1"));
        System.out.println("k2的值:"+jedis.smembers("k2"));
     //sdiff:差集
        jedis.sadd("k3","1","2","3","4","5");
        jedis.sadd("k4","1","2","3","a","b");
        System.out.println("k3和k4的差集是:"+jedis.sdiff("k3","k4"));
        System.out.println("k4和k3的差集是:"+jedis.sdiff("k4","k3"));
     //sinter:交集
        System.out.println("k3和k4的交集是:"+jedis.sinter("k3","k4"));
     //sunion:并集
        System.out.println("k3和k4的并集是:"+jedis.sunion("k3","k4"));
    }
    /**
     * Hash常用命令练习
     * KV模式不变,但Value是一个键值对
     */
    public void hashTest(Jedis jedis){
        jedis.flushAll();
     //hset:增
        jedis.hset("k1","name","zhangsan");
     //hget:查
        System.out.println("k1的值:"+jedis.hget("k1","name"));
     //hmset:一次增多个
        Map<String,String> hmap=new HashMap<>();
        hmap.put("id","1");
        hmap.put("name","王五");
        hmap.put("age","20");
        jedis.hmset("k2",hmap);
     //hmget:一次查多个
        System.out.println("k2的多个值:"+jedis.hmget("k2","age","name"));
     //hgetall:查所有
        System.out.println("k2的所有值:"+jedis.hgetAll("k2"));
     //hdel:删除指定的
        jedis.hdel("k2","age","name");
        System.out.println("删除数据后的k2的所有值:"+jedis.hgetAll("k2"));
     //hlen:长度
        Map<String,String> hhmap=new HashMap<>();
        hhmap.put("id","2");
        hhmap.put("name","王六");
        hhmap.put("age","20");
        jedis.hmset("k3",hhmap);
        System.out.println("k3的长度:"+jedis.hlen("k3"));
     //hexists key:在key里面的某个值的key
        System.out.println("k3中是否存在age:"+jedis.hexists("k3","age"));
     //hkeys:根据key获取value里所有的key
        System.out.println("k3里所有的值的key:"+jedis.hkeys("k3"));
     //hvals:根据key获取value里所有的value
        System.out.println("k3里所有的值的value:"+jedis.hvals("k3"));
     //hincrby:在某个值的基础上加多少
        jedis.hincrBy("k3","age",2);
        System.out.println("k3的age加了2后:"+jedis.hget("k3","age"));
     //hsetnx:不存在赋值,存在了无效
        long num=jedis.hsetnx("k3","age","50");
        if(num==0){
            System.out.println("k3已经存在age了");
        }
    }
    /**
     * Zset(sorted set)常用命令练习
     */
    public void zsetTest(Jedis jedis){
        jedis.flushAll();
     //zadd:增
        jedis.zadd("k1",10.0,"v1");
        Map<Double, String> scoreMap=new HashMap<>();
        scoreMap.put(20.0,"v2");
        scoreMap.put(30.0,"v3");
        scoreMap.put(40.0,"v4");
        jedis.zadd("k1",scoreMap);
     //zrange:查
        System.out.println("k1的值:"+jedis.zrange("k1",0,-1));
     //zrangebyscore  key 开始score 结束score:范围查
        System.out.println("k1 20.0到40.0的值:"+jedis.zrangeByScore("k1",20.0,40.0));
        System.out.println("k1 20.0到40.0的值:"+jedis.zrangeByScore("k1",20.0,40.0,2,2));
     //zrem key 某score下对应的value值:删除元素
        jedis.zrem("k1","v4");
        System.out.println("删除掉v4后k1的值:"+jedis.zrange("k1",0,-1));
     //zcard :获取集合中元素个数
        System.out.println("k1中的元素个数:"+jedis.zcard("k1"));
     //zcount :获取分数区间内元素个数,zcount key 开始分数区间 结束分数区间
        System.out.println("k1中10.0~30.0元素的个数:"+jedis.zcount("k1",10.0,30.0));
     //zrank: 获取value在zset中的下标位置
        System.out.println("k1中v2的下标位置:"+jedis.zrank("k1","v2"));
     //zscore:按照值获得对应的分数
        System.out.println("k1中v2的分数:"+jedis.zscore("k1","v2"));
     // zrevrank key values值:逆序获得下标值
        System.out.println("k1的v3逆序下标值:"+jedis.zrevrank("k1","v3"));
     //zrevrange:倒叙排列
        System.out.println("k1的逆序排列:"+jedis.zrevrange("k1",0,-1));
    }
}

10.2.1 事务提交

       ① 日常操作

package com.atguigu.redis.test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Response;
import redis.clients.jedis.Transaction;
public class Test03 
{
  public static void main(String[] args) 
  {
     Jedis jedis = new Jedis("127.0.0.1",6379);

   //监控key,如果改动了事务就被放弃
     /*3
     jedis.watch("serialNum");
     jedis.set("serialNum","s#####################");
     jedis.unwatch();*/

     Transaction transaction = jedis.multi();//被当作一个命令进行执行
     Response<String> response = transaction.get("serialNum");
     transaction.set("serialNum","s002");
     response = transaction.get("serialNum");
     transaction.lpush("list3","a");
     transaction.lpush("list3","b");
     transaction.lpush("list3","c");

     transaction.exec();
     //2 transaction.discard();
     System.out.println("serialNum***********"+response.get());    
  }
}

       ② 加锁操作

public class TestTransaction {
  public boolean transMethod() {
     Jedis jedis = new Jedis("127.0.0.1", 6379);
     int balance;// 可用余额
     int debt;// 欠额
     int amtToSubtract = 10;// 实刷额度

     jedis.watch("balance");
     //jedis.set("balance","5");//此句不该出现,讲课方便。模拟其他程序已经修改了该条目
     balance = Integer.parseInt(jedis.get("balance"));
     if (balance < amtToSubtract) {
       jedis.unwatch();
       System.out.println("modify");
       return false;
     } else {
       System.out.println("***********transaction");
       Transaction transaction = jedis.multi();
       transaction.decrBy("balance", amtToSubtract);
       transaction.incrBy("debt", amtToSubtract);
       transaction.exec();
       balance = Integer.parseInt(jedis.get("balance"));
       debt = Integer.parseInt(jedis.get("debt"));

       System.out.println("*******" + balance);
       System.out.println("*******" + debt);
       return true;
     }
  }
  /**
   * 通俗点讲,watch命令就是标记一个键,如果标记了一个键, 在提交事务前如果该键被别人修改过,那事务就会失败,这种情况通常可以在程序中
   * 重新再尝试一次。
   * 首先标记了键balance,然后检查余额是否足够,不足就取消标记,并不做扣减; 足够的话,就启动事务进行更新操作,
   * 如果在此期间键balance被其它人修改, 那在提交事务(执行exec)时就会报错, 程序中通常可以捕获这类错误再重新执行一次,直到成功。
   */
  public static void main(String[] args) {
     TestTransaction test = new TestTransaction();
     boolean retValue = test.transMethod();
     System.out.println("main retValue-------: " + retValue);
  }
}

10.2.1 主从复制

public static void main(String[] args) throws InterruptedException 
  {
     Jedis jedis_M = new Jedis("127.0.0.1",6379);
     Jedis jedis_S = new Jedis("127.0.0.1",6380);

     jedis_S.slaveof("127.0.0.1",6379);

     jedis_M.set("k6","v6");
     Thread.sleep(500);
     System.out.println(jedis_S.get("k6"));
  }

       ① 6379,6380启动,先各自先独立
       ② 主写
       ③ 从读

10.3 JedisPool

       ① 获取Jedis实例需要从JedisPool中获取
       ② 用完Jedis实例需要返还给JedisPool
       ③ 如果Jedis在使用过程中出错,则也需要还给JedisPool
       ④ 案例见代码
       JedisPoolUtil

package com.atguigu.redis.test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class JedisPoolUtil {

 private static volatile JedisPool jedisPool = null;//被volatile修饰的变量不会被本地线程缓存,对该变量的读写都是直接操作共享内存。

  private JedisPoolUtil() {}

  public static JedisPool getJedisPoolInstance()
 {
     if(null == jedisPool)
    {
       synchronized (JedisPoolUtil.class)
      {
          if(null == jedisPool)
         {
           JedisPoolConfig poolConfig = new JedisPoolConfig();//配置池
           poolConfig.setMaxActive(1000);  //最大链接数
           poolConfig.setMaxIdle(32);      //最大空闲
           poolConfig.setMaxWait(100*1000);//最大等待时间
           poolConfig.setTestOnBorrow(true);

          jedisPool = new JedisPool(poolConfig,"127.0.0.1");//jedis连接池的配置
         }
      }
    }
     return jedisPool;
 }

//关闭链接池,释放对象,用完了还回去
  public static void release(JedisPool jedisPool,Jedis jedis){
   if(null != jedis){
      jedisPool.returnResourceObject(jedis);
    }
 }
}

       Demo5 jedisPool.getResource();

package com.atguigu.redis.test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class Test01 {
  public static void main(String[] args) {
     JedisPool jedisPool = JedisPoolUtil.getJedisPoolInstance();//从池子中拿到对象
     Jedis jedis = null;
     try {
       jedis = jedisPool.getResource();
       jedis.set("k18","v183");
     } catch (Exception e) {
       e.printStackTrace();
     }finally{
       JedisPoolUtil.release(jedisPool, jedis);//把对象还回去,释放对象
     }
  }
}

       ⑤ 配置总结all
       JedisPool的配置参数大部分是由JedisPoolConfig的对应项来赋值的。
       maxActive:控制一个pool可分配多少个jedis实例,通过pool.getResource()来获取;如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted。
       maxIdle:控制一个pool最多有多少个状态为idle(空闲)的jedis实例;
       whenExhaustedAction:表示当pool中的jedis实例都被allocated完时,pool要采取的操作;默认有三种。
       WHEN_EXHAUSTED_FAIL –> 表示无jedis实例时,直接抛出NoSuchElementException;
       WHEN_EXHAUSTED_BLOCK –> 则表示阻塞住,或者达到maxWait时抛出JedisConnectionException;
       WHEN_EXHAUSTED_GROW –> 则表示新建一个jedis实例,也就说设置的maxActive无用;
       maxWait:表示当borrow一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛JedisConnectionException;
       testOnBorrow:获得一个jedis实例的时候是否检查连接可用性(ping());如果为true,则得到的jedis实例均是可用的;
       testOnReturn:return 一个jedis实例给pool时,是否检查连接可用性(ping());
       testWhileIdle:如果为true,表示有一个idle object evitor线程对idle object进行扫描,如果validate失败,此object会被从pool中drop掉;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义;
       timeBetweenEvictionRunsMillis:表示idle object evitor两次扫描之间要sleep的毫秒数;
       numTestsPerEvictionRun:表示idle object evitor每次扫描的最多的对象数;
       minEvictableIdleTimeMillis:表示一个对象至少停留在idle状态的最短时间,然后才能被idle object evitor扫描并驱逐;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义;
       softMinEvictableIdleTimeMillis:在minEvictableIdleTimeMillis基础上,加入了至少minIdle个对象已经在pool里面了。如果为-1,evicted不会根据idle time驱逐任何对象。如果minEvictableIdleTimeMillis>0,则此项设置无意义,且只有在timeBetweenEvictionRunsMillis大于0时才有意义;
       lifo:borrowObject返回对象时,是采用DEFAULT_LIFO(last in first out,即类似cache的最频繁使用队列),如果为False,则表示FIFO队列;


       其中JedisPoolConfig对一些参数的默认设置如下:
       testWhileIdle=true
       minEvictableIdleTimeMills=60000
       timeBetweenEvictionRunsMillis=30000
       numTestsPerEvictionRun=-1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值