Redis——数据结构/如何使用/代码示例

1.redis常见数据结构以及使用场景分析

(1)String:key+value的形式,即一个Key对应一个value

String数据结构是简单的key-value类型,value其实不仅可以是String,也可以是数字。 常规key-value缓存应用; 常规计数:微博数,粉丝数等

(2)Hash:key + name-value的形式,即一个key对应一个Map(存放多个键值对),这个Map像一个对象一样,键为属性名,值为属性值;

hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象,后续操作的时候,你可以直接仅仅修改这个对象中的某个字段的值。 比如我们可以 hash 数据结构来存储对象,如用户信息,商品信息等等。

(3)List:key + {value1, value2, value3, ...}  即多个value构成一个List,这个List对应一个Key;

list 就是链表,Redis list 的应用场景非常多,也是Redis最重要的数据结构之一,比如微博的关注列表,粉丝列表,消息列表等功能都可以用Redis的 list 结构来实现。

另外可以通过 lrange 命令,就是从某个元素开始读取多少个元素,可以基于 list 实现分页查询,这个很棒的一个功能,基于 redis 实现简单的高性能分页,可以做类似微博那种下拉不断分页的东西(一页一页的往下走),性能高。

(4)Set:key + {value1, value2, value3, ...},与List类似,无序,无重复value;

set 对外提供的功能与list类似是一个列表的功能,特殊之处在于 set 是可以自动排重的。

当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。

可以基于 set 轻易实现交集、并集、差集的操作。

比如:在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。

Redis可以非常方便的实现如共同关注、共同粉丝、共同喜好等功能。这个过程也就是求交集的过程,具体命令如下:

sinterstore key1 key2 key3     // 将交集存在key1内

(5)Sorted Set:key + {value1-score, value2-score, value3-score, ...},与Set相比,每个集合元素value都多了个score属性,作为排序的依据;

和set相比,sorted set增加了一个权重参数score,使得集合中的元素能够按score进行有序排列。

举例: 在直播系统中,实时排行信息包含直播间在线用户列表,各种礼物排行榜,弹幕消息(可以理解为按消息维度的消息排行榜)等信息,适合使用 Redis 中的 Sorted Set 结构进行存储。

2. redis在项目中的使用示例:

(1)本次的redis操作主要是针对String的(放已报名总人数),如下:

查找/设置redis:

 redis操作的Api路径:package redis.clients.jedis;

(2)ZSet(key-value+score):消费排行

(3) HashMap(key-key/value)一般一个map对象对应一个对象,其key/value为对象属性名/值:

3.Redis的操作API示例代码(包括连接和API命令)

    <!-- redis依赖 https://mvnrepository.com/artifact/redis.clients/jedis -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>3.0.1</version>
    </dependency>
package jedis;

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

/**
 * @author A
 * redis 连接工具类
 */
public class JedisUtils {

    private static JedisPoolConfig config;
    private static JedisPool pool;

    static {
        config = new JedisPoolConfig();
        //最大连接数, 默认8个
        config.setMaxTotal(30);
        //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值是8。
        config.setMaxIdle(2);
        //连接超时时是否阻塞,false时报异常,ture阻塞直到超时, 默认true
        config.setBlockWhenExhausted(true);
        //逐出策略(默认DefaultEvictionPolicy(当连接超过最大空闲时间,或连接数超过最大空闲连接数))
        config.setEvictionPolicyClassName("org.apache.commons.pool2.impl.DefaultEvictionPolicy");
        //获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1
        config.setMaxWaitMillis(-1);
        //逐出连接的最小空闲时间 默认1800000毫秒(30分钟)
        config.setMinEvictableIdleTimeMillis(1800000);
        //最小空闲连接数, 默认0
        config.setMinIdle(0);
        //每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3
        config.setNumTestsPerEvictionRun(3);
        //对象空闲多久后逐出, 当空闲时间>该值 且 空闲连接>最大空闲数 时直接逐出,不再根据MinEvictableIdleTimeMillis判断  (默认逐出策略)
        config.setSoftMinEvictableIdleTimeMillis(1800000);
        // 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,
        // 默认-1
        config.setMaxWaitMillis(100);
        //对拿到的connection进行validateObject校验
        config.setTestOnBorrow(true);
        //在进行returnObject对返回的connection进行validateObject校验
        config.setTestOnReturn(true);
        //定时对线程池中空闲的链接进行validateObject校验
        config.setTestWhileIdle(true);
        //本机redis地址
        pool = new JedisPool(config, "127.0.0.1", 6379);
    }

    /**
     * 获取连接的方法
     * @return
     */
    public static Jedis getJedis() {
        return pool.getResource();
    }

    /**
     * 释放连接
     * @param j
     */
    public static void closeJedis(Jedis j) {
        j.close();
    }
}
package jedis;

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

import org.junit.After;
import org.junit.Before;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;

/**
 * @author A
 */

public class TestRedis {

    static Jedis jedis = JedisUtils.getJedis();

    @Test
    public void testString() {
        // redis存储字符串
        // -----添加数据----------
        jedis.set("name", "a");// 向key-->name中放入了value-->xinxin
        System.out.println(jedis.get("name"));// 执行结果:xinxin
        jedis.append("name", " b"); // 拼接
        System.out.println(jedis.get("name"));
        jedis.del("name"); // 删除某个键
        System.out.println(jedis.get("name"));
        // 设置多个键值对
        jedis.mset("name", "zhangsan", "age", "23", "qq", "xxxxxxxxxxx");
        jedis.incr("age"); // 进行加1操作
        System.out.println(jedis.get("name") + "-" + jedis.get("age") + "-" + jedis.get("qq"));
    }

    @Test
    public void testMap() {
        // redis操作Map
        // -----添加数据----------
        Map<String, String> map = new HashMap<String, String>();
        map.put("name", "a");
        map.put("age", "22");
        map.put("qq", "xxxxx");
        jedis.hmset("user", map);
        // 取出user中的name,注意结果是一个泛型的List
        // 第一个参数是存入redis中map对象的key,后面跟的是放入map中的对象的key,后面的key可以跟多个,是可变参数
        List<String> rsmap = jedis.hmget("user", "name", "age", "qq");
        System.out.println(rsmap);
        // 删除map中的某个键值
        jedis.hdel("user", "age");
        System.out.println(jedis.hmget("user", "age")); // 因为删除了,所以返回的是null
        System.out.println(jedis.hlen("user")); // 返回key为user的键中存放的值的个数2
        System.out.println(jedis.exists("user"));// 是否存在key为user的记录 返回true
        System.out.println(jedis.hkeys("user"));// 返回map对象中的所有key
        System.out.println(jedis.hvals("user"));// 返回map对象中的所有value
        Iterator<String> iter = jedis.hkeys("user").iterator();
        while (iter.hasNext()) {
            String key = iter.next();
            System.out.println(key + ":" + jedis.hmget("user", key));
        }
    }

    @Test
    public void testList() {
        // jedis操作List
        // 开始前,先移除所有的内容
        jedis.del("java framework");
        System.out.println(jedis.lrange("java framework", 0, -1));
        // 先向key java framework中存放三条数据
        jedis.lpush("java framework", "spring");
        jedis.lpush("java framework", "struts");
        jedis.lpush("java framework", "hibernate");
        // 再取出所有数据jedis.lrange是按范围取出,
        // 第一个是key,第二个是起始位置,第三个是结束位置,jedis.llen获取长度 -1表示取得所有
        System.out.println(jedis.lrange("java framework", 0, -1));
        jedis.del("java framework");
        jedis.rpush("java framework", "spring");
        jedis.rpush("java framework", "struts");
        jedis.rpush("java framework", "hibernate");
        System.out.println(jedis.lrange("java framework", 0, -1));
    }

    @Test
    public void testSet() {
        // jedis操作Set
        // 清空数据
        System.out.println(jedis.flushDB());
        // 添加
        jedis.sadd("name", "a");
        jedis.sadd("name", "b");
        jedis.sadd("name", "c");
        jedis.sadd("name", "d");
        jedis.sadd("name", "e");
        // 移除noname
        jedis.srem("name", "c");
        System.out.println(jedis.smembers("name"));// 获取所有加入的value
        System.out.println(jedis.sismember("name", "c"));// 判断 c 是否是user集合的元素
        System.out.println(jedis.srandmember("name")); // 返回集合中的一个随机元素
        System.out.println(jedis.scard("name"));// 返回集合的元素个数
    }

    @Test
    public void testZSet() {
        // jedis操作ZSet
        jedis.zadd("hackers", 1940, "Alan Kay");
        jedis.zadd("hackers", 1953, "Richard Stallman");
        jedis.zadd("hackers", 1965, "Yukihiro Matsumoto");
        jedis.zadd("hackers", 1916, "Claude Shannon");
        jedis.zadd("hackers", 1969, "Linus Torvalds");
        jedis.zadd("hackers", 1912, "Alan Turing");
        Set<String> setValues = jedis.zrange("hackers", 0, -1);//zset中的所有元素
        System.out.println(setValues);
        Set<String> setValues2 = jedis.zrevrange("hackers", 0, -1);//按分数值递减(从大到小)来排列
        System.out.println(setValues2);
        // 清空数据
        System.out.println(jedis.flushDB());
        // 添加数据
        jedis.zadd("zset", 10.1, "hello");
        jedis.zadd("zset", 10.0, ":");
        jedis.zadd("zset", 9.0, "zset");
        jedis.zadd("zset", 11.0, "zset!");
        // 元素个数
        System.out.println(jedis.zcard("zset"));
        // 元素下标
        System.out.println(jedis.zscore("zset", "zset"));
        // 集合子集
        System.out.println(jedis.zrange("zset", 0, -1));
        // 删除元素
        System.out.println(jedis.zrem("zset", "zset!"));
        System.out.println(jedis.zcount("zset", 9.5, 10.5));
        // 整个集合值
        System.out.println(jedis.zrange("zset", 0, -1));
    }

    @Test
    public void testLuaScript() {

    }

    @After
    private void destroy() {
        jedis.flushDB();
        JedisUtils.closeJedis(jedis);
    }

    public static void main(String[] args) {
        new TestRedis().destroy();
    }

}

4.使用方法命令参考:

Jedis/JedisCluster的使用

使用文档

Redis命令参考 (这个网站很好用!!!

​​​​​​Redis 数据类型 | 菜鸟教程

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值