Jedis操作redis基础

1.mavn依赖

<!-- 引入redis客户端依赖 -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.4.2</version>
</dependency>

 2.redis数据格式

字符串(String)可以被编码为 raw (常规字符串) 或者int (用字符串表示64位无符号整数这种编码方式是为了节省空间).

列表类型(List)可以被编码为ziplist 或者 linkedlist. ziplist 是为了节省较小的列表空间而设计一种特殊编码方式.

集合(Set)被编码为 intset 或者 hashtable. intset 是为了存储数字的较小集合而设计的一种特殊编码方式.

哈希表(Hash)可以被编码为 zipmap 或者hashtable. zipmap 是专为了较小的哈希表而设计的一种特殊编码方式

有序集合(Sorted Set)被编码为ziplist 或者 skiplist 格式. ziplist可以表示较小的有序集合, skiplist 表示任意大小多的有序集合.

4.String类型

String是简单的key-value类型,value其实不仅是String,也可以是数字。

实现方式:String在redis内部存储默认就是一个字符串,被redisObject所引用,当遇到incr,decr等操作时会转成数值型进行计算,此时redisObject的encoding字段为int。

jedis 

jedis.set(key, value); //增加&修改
jedis.del(key) //删除
jedis.setex(key, expireSecond, value); //设置超期时间

jedis.mset("key01","value01","key02","value02","key03","value03"));
jedis.mget("key01","key02","key03"));

jedis.del(new String[]{"key01","key02"})
jedis.setnx("key1", "value1") //新增键值对防止覆盖原先值
jedis.getSet(key,newValue)// 设置为新value 但返回旧value

//memcached和redis同样有append的操作,但是memcached有prepend的操作,redis中并没有。
jedis.append("key3", "End") 

jedis.incr("key1") //加1
jedis.decr("key2") //减1
jedis.incrBy("key1", n) //加n decrBy 减n

command命令 

1)设置一个字符串值 

  语法:set key  value

eg: set userId "12232"

(2)得到一个字符串的值

 语法:get key

eg:get userId

(3)删除一个key

 del key

eg:del userId

5.List

常用命令:lpush,rpush,lpop,rpop,lrange等。

实现方式: 
Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。

jedis 

 1). 右边入队:jedis.rpush("collections", "ArrayList", "Vector")
              jedis.rpush("userList", "James"); 
 2). 左边出队:右边出栈(rpop),即为对堆栈的操作 压栈 弹栈
              jedis.lpop("userList");  
 3). 返回列表范围:从0开始,到最后一个(-1) [包含] 
              List<String> userList = jedis.lrange("userList", 0, -1);  
              Redis的TopN操作,即使用list完成:lrange
              //获取collections下标为2的元素
              jedis.lindex("collections", 2)
 4). 删除:使用key jedis.del("userList");  
      //删除列表指定的值 ,第二个参数为删除的个数(有重复时),后add进去的值先被删,类似于出栈
      jedis.lrem("collections", 2, "HashMap")
 5). 设置:位置1处为新值----区别于入队
               jedis.lset("userList", 1, "Nick Xu"); 
 6). 返回长度:Long size = jedis.llen("userList");  
 7). 进行裁剪:包含 jedis.ltrim("userList", 1, 2);  

command命令

edis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。是有顺序的,第一条插入的在最上面

(1)设置值

语法:lpush key value

eg:

lpush nosql redis

lpush nosql mongdb

lpush nosql mecache

(2)得到一个list

 lrange key  开始数  结束数  (注意包含开始和结束)

eg:

lrange nosql 0,1  //获得2条数据 0,1

(3)删除一个hash值

 del key

eg:

del nosql

6.set

Set是一堆不重复值,无序的组合。set 的内部实现是一个 value永远为null的HashMap,实际就是通过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的原因。

jedis

jedis.sadd("fruit", "pear", "watermelon");   添加到set:可一次添加多个
Set<String> fruit = jedis.smembers("fruit");   遍历集合
jedis.srem("fruit", "pear");  移除元素:remove
jedis.scard("fruit");  返回长度
jedis.sismember("fruit", "pear"); 是否包含

jedis.smove("fruit", "food", "cookie")  将cookie从fruit移入food中
jedis.spop("fruit") //随机移除一个元素

jedis.sadd("food", "bread", "milk");   
//集合的交运算(sinter)、差集(sdiff)、并集(sunion)
Set<String> fruitFood = jedis.sunion("fruit", "food");  

command

Redis 的 Set 是 string 类型的无序集合。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。

注意:增加要去重

(1)设置set值

语法:sadd key 值

eg:

sadd nosql redis

sadd nosql mecache

sadd nosql mongdb

sadd nosql mongdb

 

7.zset

有序集合在集合的基础上,增加了一个用于排序的参数,通过用户额外提供一个优先级(score)的参数来为成员排序。

Redis sorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里存放的是所有的成员,排序依据是HashMap里存的score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。

jedis.zadd("user", 22, "James");  //第二个参数为score
jedis.zadd("user", 24, "James");  //更新score
Set<String> user = jedis.zrange("user", 0, -1);  zset的范围:找到从0到-1的所有元素

SortingParams sortingParameters = new SortingParams(); 
jedis.sort(key, sortingParameters.asc()) 按照指定方式对value排序

有序集合

Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

zset的成员是唯一的,但分数(score)却可以重复。

(1)设置zset值

语法:zadd key score value //sore是确定显示的顺序,值越小排到最前面

eg:

zadd home 0 jzk

zadd home  1 xhp

zadd home 2 jth

zadd  home 1 jfy

 

(2)得到zsetz值

zrangebyscore key min_score max_score

获得值,score在给出的值内(包含)

zrange key 开始值 结束值

语法和set一致

(3)删除zset值

del key

eg:

del home

8.hash

在Memcached中,我们经常将一些结构化的信息打包成HashMap,在客户端序列化后存储为一个字符串的值,比如用户的昵称、年龄、性别、积分等,这时候在需要修改其中某一项时,通常需要将所有值取出反序列化后,修改某一项的值,再序列化存储回去。这样不仅增大了开销,也不适用于一些可能并发操作的场合(比如两个并发的操作都需要修改积分)。而Redis的Hash结构可以使你像在数据库中Update一个属性一样只修改某一项属性值。

Redis的Hash实际是内部存储的Value为一个HashMap,并提供了直接存取这个Map成员的接口。这样对数据的修改和存取都可以直接通过其内部Map的 Key(Redis里称内部Map的key为field), 也就是通过 key+ field就可以操作对应属性数据了,既不需要重复存储数据,也不会带来序列化和并发修改控制的问题。

需要注意的是,Redis提供了接口(hgetall)可以直接取到全部的属性数据,但是如果内部Map的成员很多,那么涉及到遍历整个内部 Map的操作,由于Redis单线程模型的缘故,这个遍历操作可能会比较耗时,而令其它客户端的请求完全不响应。

1). 存放数据:使用HashMap
      Map<String, String>  capital = new HashMap<String, String>();  
      capital.put("shannxi", "xi'an");  
      ...  
      jedis.hmset("capital", capital);  
      jedis.hset("hash", "key5", "value5");
2 ) 获取数据
      List<String> cities = jedis.hmget("capital", "shannxi", "shanghai");  

      Map<String, String> map=jedis.hgetAll(String key)//所有键值对
      jedis.hkeys("hash") 所有键
      jedis.hvals("hash") 所有值
      jedis.hincrBy("hash", "key6", 6) 将key6保存的值加上一个整数,如果key6不存在则添加key6
      hdel("hash", "key2") 删除一个或者多个键值对
      jedis.hlen("hash") 散列hash中键值对的个数
      jedis.hexists("hash","key2") 判断hash中是否存在key2

Redis hash 是一个键值(key=>value)对集合。

Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。

(1)设置一个hash值

 语法:HMSET key  filed1 field1_value   filed2 field2_value  ...

eg:

hmset user id "1"  userName "jiangzk" birth "1978-06-10"

 

(2)得到hash的一个属性值

语法:hget key filed

eg:

 hget user userName   //得到key user的一个字段userName的值

 

(3)删除一个hash值

 del key

eg:

del user

9.redis中list set zset的区别

3.附工具类

package com.jyj.comm;

import redis.clients.jedis.Jedis;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @class: com.jyj.comm.RedisUtil
 * @description:jredis操作的封装类
 * @author: jiangzengkui
 * @company: 教育家
 * @create: 2021-01-19 16:55
 */
public class RedisUtil {


    /****************************************字符串操作***********************/

    /**
     * 新增字符串key,无则新增,有则覆盖
     * @param jedis
     * @param key
     * @param cont
     */
    public static  void str_add(Jedis jedis,String key,String cont){

        jedis.set(key,cont);
    }



    /**
     * 新增多个,
     * @param jedis
     * @param keysvalues "key1","kval1","key2","keyval2" ..
     */
    public static  void str_adds(Jedis jedis,String... keysvalues){
        jedis.mset(keysvalues);
    }



    /**
     * 得到一个内容,如果key不存在,则返回null
     * @param jedis
     * @param key
     * @return
     */
    public static String str_getByKey(Jedis jedis,String key){

        return jedis.get(key);
    }

    /**
     * 得到多个key值
     * @param jedis
     * @param keys eg: "k1","k2"
     * @return
     */
    public static List<String> str_getbyKeys(Jedis jedis, String... keys){
        return jedis.mget(keys);
    }



    /****************************hash操作************************************/
    /**
     * 通过map写入
     * @param jedis
     * @param key
     * @param map
     */
    public static  void hash_addByMap(Jedis jedis,String key,Map <String,String> map){
        jedis.hmset(key,map);
    }

    /**
     * 增加hash类型,一个字段一个字段的增加
     * @param jedis
     * @param key
     * @param field
     * @param val
     */
    public static  void hash_addFieldVal(Jedis jedis,String key,String field,String val){

        jedis.hset(key, field,val);

    }

    /**
     * 得到一个hash类型的所有字段值
     * @param jedis
     * @param key
     * @return
     */
    public static  Map <String,String>  hash_getAll(Jedis jedis,String key){
        return jedis.hgetAll(key);
    }

    /**
     * 通过传递字段获得值
     * @param jedis
     * @param key
     * @param fields
     * @return
     */
    public static List<String> hash_getValByField(Jedis jedis,String key,String... fields){


        return jedis.hmget(key, fields);

    }

    /**
     * 移除hash的值
     * @param jedis
     * @param key
     * @param fields
     */
    public static  void hash_removdVal(Jedis jedis,String key,String... fields){
        jedis.hdel(key, fields); //删除一个或者多个键值对
    }

    /**
     * 得到长度
     * @param jedis
     * @param key
     * @return
     */
    public static long hash_getLen(Jedis jedis,String key){
        return  jedis.hlen(key);
    }

    /**
     * 字段是否存在
     * @param jedis
     * @param key
     * @param filed
     * @return
     */
    public static  boolean hash_fieldIsExist(Jedis jedis,String key,String filed){
        return jedis.hexists(key,filed) ;//判断hash中是否存在key2
    }



    /****************************************整数加减的操作***********************/
    /***注意:redis没有存储指定数字的方法,可以以字符串存储读出来再转化**/


    /**
     * 如果没有key,则创建,初始值为1,如果有,则在原值加1
     * @param jedis
     * @param key
     */
    public static  void  incr(Jedis jedis,String key){
        jedis.incr("key1");
    }


    /**
     * 如果没有key,则创建,初始值为-1,如果有,则在原值减1
     * @param jedis
     * @param key
     */
    public static  void  decr(Jedis jedis,String key){
        jedis.decr(key) ;
    }

    /**
     * 加减n
     * @param jedis
     * @param key
     * @param n
     */
    public static  void  incrBy(Jedis jedis,String key,int n){
        jedis.incrBy(key,n) ;
    }






/****************************list操作************************************/

    /**
     * 增加list数据类型,注意,不会去重
     * @param jedis
     * @param key
     * @param values
     */
    public static void list_add(Jedis jedis,String key,String... values){
        jedis.lpush(key,values);
    }

    /**
     * 得到所有list数据
     * @param jedis
     * @param key
     * @return
     */
    public static List<String> list_getAll(Jedis jedis,String key){
        return  jedis.lrange(key,0,-1) ;
    }

    /**
     * 得到list
     * @param jedis
     * @param key
     * @param start 开始索引
     * @param end  结束索引 -1表示到最后一个索引
     * @return
     */
    public static  List<String> list_getByIndex(Jedis jedis,String key,int start,int end){
        List<String> list = jedis.lrange(key, start ,end);
        return  list;
    }

/****************************set操作************************************/
/**
 Set是一堆不重复值,无序的组合。set 的内部实现是一个 value永远为null的HashMap,实际就是通过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的原因。
 */
    /**
     * 新增set类型,会去重
     * @param jedis
     * @param key
     * @param vals
     */
    public static void set_add(Jedis jedis,String key,String... vals){
    jedis.sadd(key,vals);
}

    /**
     * 删除set对应的值
     * @param jedis
     * @param key
     * @param vals
     */
    public static void  set_remove(Jedis jedis,String key,String... vals){
        jedis.srem(key,vals);
    }

    /**
     * 得到set集合的值
     * @param jedis
     * @param key
     * @return
     */
    public  Set<String> set_getAll(Jedis jedis,String key){
        return  jedis.smembers(key);
    }

    /**
     * 得到set长度,不存在返回0
     * @param jedis
     * @param key
     * @return
     */
    public static Long set_getLen(Jedis jedis,String key){
      return jedis.scard(key);
    }

    /**
     * 值在set里是否存在
     * @param jedis
     * @param key
     * @param val
     * @return
     */
    public static boolean set_isExist(Jedis jedis,String key,String val){
        return jedis.sismember(key, val);
    }


/****************************zset操作************************************/
/**
 set是有序的排列,去重
 */
    /**
     * 新增一个zset成员 score是用来排序的
     * @param jedis
     * @param key
     * @param score
     * @param member
     */
    public static void zset_add(Jedis jedis,String key,double score,String member){
    jedis.zadd(key, score,member);
    }

    /**
     * 新增多个zset
     * @param jedis
     * @param key
     * @param map
     */
    public static void zset_adds(Jedis jedis,String key,Map<String ,Double> map){
        jedis.zadd(key,map);
    }

    /**
     * 得到一个zset的集合
     * @param jedis
     * @param key
     * @return
     */
    public static Set<String> zset_getAll(Jedis jedis,String key){
        return jedis.zrange(key, 0, -1);
    }

    /****************************通用操作************************************/
    /**
     * 删除一个key
     * @param jedis
     * @param key
     */

    public static void comm_delKey(Jedis jedis,String key) {
        if(jedis.exists(key)){

            jedis.del(key);
            System.out.println("删除成功,key="+key);
        }
    }

    /**
     * 设置过期时间
     * @param jedis
     * @param key
     * @param seconds
     */
    public static void comm_setExpireTime(Jedis jedis,String key,int seconds){
        jedis.expire(key, seconds);
    }
    /**
     * 删除多个key
     * @param jedis
     * @param keys  eg:"k1","k2"
     */
    public static void comm_delKeys(Jedis jedis,String... keys){
        jedis.del(keys);

    }

    /**
     * 删除所有key
     * @param jedis
     */
    public static void comm_delAll(Jedis jedis){
        System.out.println("清空库中所有数据:"+jedis.flushDB());
    }

    /**
     * 得到所有key
     * @param jedis
     * @return
     */
    public  static Set<String> comm_getAllKey(Jedis jedis){
        // 获取数据并输出
        Set<String> keys = jedis.keys("*");
        return keys;
    }


    /**
     * 链接jdis
     * @return
     */
    public  static  Jedis getJedis(){
        //连接本地的 Redis 服务
        Jedis jedis = new Jedis("localhost",6379,2000);
        //   jedis.auth("segns");//设置密码
        System.out.println("连接成功");
        return jedis;
    }
}

8.连接池

单个连接开销太大,则用连接池进行处理

 <!-- 引入redis客户端依赖 -->
  <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>2.4.2</version>
  </dependency>
<!--配合redis连接池用,好像不用也可以 -->
<dependency>
  <groupId>commons-pool</groupId>
  <artifactId>commons-pool</artifactId>
  <version>1.5.4</version>
</dependency>

连接池代码

package com.jyj.comm;

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

/**
 * @class: com.jyj.comm.RedisPoolUtil
 * @description: 连接池的配置
 * @author: jiangzengkui
 * @company: 教育家
 * @create: 2021-01-20 17:42
 */
public class RedisPoolUtil {
    /**
     * 配置这些可以写到配置文件里
     */
    //Redis服务器IP
    private static String ADDR = "127.0.0.1";

    //Redis的端口号
    private static int PORT = 6379;

    //访问密码
    private static String AUTH = "1234";

    //可用连接实例的最大数目,默认值为8;
    //如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
    private static int MAX_TOTAL = 8;

    //最小空闲连接数, 默认0
    private static int MIN_IDLE=0;

    //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。
    //最大空闲连接数, 默认8个
    private static int MAX_IDLE = 8;

    //获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1
    //等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException;
    private static int MAX_WAIT = -1;

    private static int TIMEOUT = 10000;

    //连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true
    private static boolean BLOCK_WHEN_EXHAUSTED = false;

    //设置的逐出策略类名, 默认DefaultEvictionPolicy(当连接超过最大空闲时间,或连接数超过最大空闲连接数)
    private static String EVICTION_POLICY_CLASSNAME="org.apache.commons.pool2.impl.DefaultEvictionPolicy";

    //是否启用pool的jmx管理功能, 默认true
    private static boolean JMX_ENABLED=true;

    //MBean ObjectName = new ObjectName("org.apache.commons.pool2:type=GenericObjectPool,name=" + "pool" + i); 默认为"pool", JMX不熟,具体不知道是干啥的...默认就好.
    private static String JMX_NAME_PREFIX="pool";

    //是否启用后进先出, 默认true
    private static boolean LIFO=true;

    //逐出连接的最小空闲时间 默认1800000毫秒(30分钟)
    private static long MIN_EVICTABLE_IDLE_TIME_MILLIS=1800000L;

    //对象空闲多久后逐出, 当空闲时间>该值 且 空闲连接>最大空闲数 时直接逐出,不再根据MinEvictableIdleTimeMillis判断  (默认逐出策略)
    private static long SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS=1800000L;

    //每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3
    private static int NUM_TESTS_PER_EVICYION_RUN=3;

    //在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;
    //在获取连接的时候检查有效性, 默认false
    private static boolean TEST_ON_BORROW = false;

    //在空闲时检查有效性, 默认false
    private static boolean TEST_WHILEIDLE=false;

    //逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
    private static long TIME_BERWEEN_EVICTION_RUNS_MILLIS=-1;

    private static JedisPool jedisPool = null;

    /**
     * 初始化Redis连接池
     */
    static {
        try {
            JedisPoolConfig config = new JedisPoolConfig();
            config.setBlockWhenExhausted(BLOCK_WHEN_EXHAUSTED);
            config.setEvictionPolicyClassName(EVICTION_POLICY_CLASSNAME);
            config.setJmxEnabled(JMX_ENABLED);
            config.setJmxNamePrefix(JMX_NAME_PREFIX);
            config.setLifo(LIFO);
            config.setMaxIdle(MAX_IDLE);
            config.setMaxTotal(MAX_TOTAL);
            config.setMaxWaitMillis(MAX_WAIT);
            config.setMinEvictableIdleTimeMillis(MIN_EVICTABLE_IDLE_TIME_MILLIS);
            config.setMinIdle(MIN_IDLE);
            config.setNumTestsPerEvictionRun(NUM_TESTS_PER_EVICYION_RUN);
            config.setSoftMinEvictableIdleTimeMillis(SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS);
            config.setTestOnBorrow(TEST_ON_BORROW);
            config.setTestWhileIdle(TEST_WHILEIDLE);
            config.setTimeBetweenEvictionRunsMillis(TIME_BERWEEN_EVICTION_RUNS_MILLIS);

            jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT, AUTH);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取Jedis实例
     * @return
     */
    public synchronized static Jedis getJedis() {
        try {
            if (jedisPool != null) {
                Jedis resource = jedisPool.getResource();
                return resource;
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 释放jedis资源
     * @param jedis
     */
    public static void close(final Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }
}

代码地址

https://gitee.com/jiangsanwa/redis

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值