Redis的数据功能

String类型的数据

(常作为缓存使用)

插入和读取一条string类型的数据

127.0.0.1:6379> set sessionid-0001 "zhangsan"
OK
127.0.0.1:6379> get sessionid-0001

对string类型数据进行增减(前提是这条数据的value可以看成数字)

DECR key

INCR key 



DECRBY key decrement

INCRBY key increment
127.0.0.1:6379> set a 1
OK
127.0.0.1:6379> get a
"1"
127.0.0.1:6379> decr a
(integer) 0
127.0.0.1:6379> incr a
(integer) 1
127.0.0.1:6379> incr a
(integer) 2
127.0.0.1:6379> get a
"2"
127.0.0.1:6379> incrby a 10
(integer) 12
127.0.0.1:6379> decrby a 10
(integer) 2

一次性插入或者获取多条数据

MGET  key1  key2

MSET  key1  value1   key2  value2  …..
127.0.0.1:6379> MSET A1 1 A2 2 A3 3
OK
127.0.0.1:6379> MGET A1 A2 A3
1) "1"
2) "2"
3) "3"

在插入一条string类型数据的同时为它指定一个存活期限

setex  bancao  10  weige

### bancao这条数据就只会存活10秒钟,过期会被redis自动清除

将一个自定义的对象存入redis

应用:将一个自定义的对象比如product存入redis

实现方式一:将对象序列化成byte数组

/**

 * 将对象缓存到redis的string结构数据中

 * @throws Exception

 *

 */

@Test

public void testObjectCache() throws Exception{

    ProductInfo p = new ProductInfo();

    p.setName("小米手机");

    p.setDescription("小米发烧专用");

    p.setCatelog("手机");

    p.setPrice(6666);



    //将对象序列化成字节数组

    ByteArrayOutputStream ba = new ByteArrayOutputStream();

    ObjectOutputStream oos = new ObjectOutputStream(ba);

    //用对象序列化流来将p对象序列化,然后把序列化之后的二进制数据写到ba流中

    oos.writeObject(p);

    //将ba流转成byte数组

    byte[] pBytes = ba.toByteArray();

    //将对象序列化之后的byte数组存到redis的string结构数据中

    jedis.set("product:01".getBytes(), pBytes);

    //根据key从redis中取出对象的byte数据

    byte[] pBytesResp = jedis.get("product:01".getBytes());

    //将byte数据反序列出对象

    ByteArrayInputStream bi = new ByteArrayInputStream(pBytesResp);

    ObjectInputStream oi = new ObjectInputStream(bi);

    //从对象读取流中读取出p对象

    ProductInfo pResp = (ProductInfo) oi.readObject();

    System.out.println(pResp);

}

实现方式二:

将对象转成json字符串来存取

/**

 * 将对象转成json字符串缓存到redis的string结构数据中

 */

@Test

public void testObjectToJsonCache(){

    ProductInfo p = new ProductInfo();

    p.setName("vivo手机");

    p.setDescription("照亮你的美");

    p.setCatelog("手机");

    p.setPrice(5000);



    //利用gson将对象转成json串

    Gson gson = new Gson();

    String pJson = gson.toJson(p);

    //将json串存入redis

    jedis.set("prodcut:02", pJson);

    //从redis中取出对象的json串

    String pJsonResp = jedis.get("prodcut:02");

    //将返回的json解析成对象

    ProductInfo pResponse = gson.fromJson(pJsonResp, ProductInfo.class);

    //显示对象的属性

    System.out.println(pResponse);

}

List数据结构

List图示

这里写图片描述

List功能演示

从头部(左边)插入数据

redis>LPUSH  key  value1  value2  value3   
127.0.0.1:6379> LPUSH  aaa aaa1 aaa2 aaa3
(integer) 3

从尾部(右边)插入数据

redis>RPUSH  key  value1  value2  value3  
127.0.0.1:6379> RPUSH  bbb bbb1 bbb2 bbb3
(integer) 3

读取list中指定范围的values

redis>LRANGE  key  start   end

redis> lrange  task-queue  0  -1      读取整个list
127.0.0.1:6379> LRANGE aaa 0 2
1) "aaa3"
2) "aaa2"
3) "aaa1"
127.0.0.1:6379> LRANGE bbb 0 2
1) "bbb1"
2) "bbb2"
3) "bbb3"
127.0.0.1:6379> LRANGE bbb 0 -1
1) "bbb1"
2) "bbb2"
3) "bbb3"

从头部弹出一个元素

LPOP  key
127.0.0.1:6379> LPOP aaa
"aaa3"
127.0.0.1:6379> LRANGE aaa 0 2
1) "aaa2"
2) "aaa1"

从尾部弹出一个元素

RPOP  key
127.0.0.1:6379> RPOP aaa
"aaa1"
127.0.0.1:6379> LRANGE aaa 0 -1
1) "aaa2"

从一个list的尾部弹出一个元素插入到另一个list

RPOPLPUSH   key1    key2     ## 这是一个原子性操作

List的应用案例demo

需求描述

任务调度系统:

生产者不断产生任务,放入task-queue排队

消费者不断拿出任务来处理,同时放入一个tmp-queue暂存,如果任务处理成功,则清除tmp-queue,否则,将任务弹回task-queue。

这里写图片描述

这里写图片描述

代码实现

生产者——模拟产生任务

public class TaskProducer {



         // 获取一个redis的客户端连接对象

         public static Jedis getRedisConnection(String host, int port) {



                   Jedis jedis = new Jedis(host, port);



                   return jedis;



         }



         public static void main(String[] args) {



                   Jedis jedis = getRedisConnection("angelababy", 6379);



                   Random random = new Random();

                   // 生成任务

                   while (true) {



                            try {

                                     // 生成任务的速度有一定的随机性,在1-2秒之间

                                     Thread.sleep(random.nextInt(1000) + 1000);

                                     // 生成一个任务

                                     String taskid = UUID.randomUUID().toString();



                                     // 往任务队列"task-queue"中插入,第一次插入时,"task-queue"还不存在

                                     //但是lpush方法会在redis库中创建一条新的list数据

                                     jedis.lpush("task-queue", taskid);

                                     System.out.println("向任务队列中插入了一个新的任务: " + taskid);



                            } catch (InterruptedException e) {

                                     // TODO Auto-generated catch block

                                     e.printStackTrace();

                            }



                   }



         }



}

消费者——模拟处理任务,并且管理暂存队列

public class TaskConsumer {



         public static void main(String[] args) {



                   Jedis jedis = new Jedis("angelababy", 6379);

                   Random random = new Random();



                   while (true) {



                            try {

                                     // 从task-queue中取一个任务,同时放入"tmp-queue"

                                     String taskid = jedis.rpoplpush("task-queue", "tmp-queue");



                                     // 模拟处理任务

                                     Thread.sleep(1000);



                                     // 模拟有成功又有失败的情况

                                     int nextInt = random.nextInt(13);

                                     if (nextInt % 7 == 0) { // 模拟失败的情况



                                               // 失败的情况下,需要将任务从"tmp-queue"弹回"task-queue"

                                               jedis.rpoplpush("tmp-queue", "task-queue");

                                               System.out.println("-------任务处理失败: " + taskid);



                                     } else { // 模拟成功的情况



                                               // 成功的情况下,将任务从"tmp-queue"清除

                                               jedis.rpop("tmp-queue");

                                               System.out.println("任务处理成功: " + taskid);



                                     }



                            } catch (InterruptedException e) {

                                     // TODO Auto-generated catch block

                                     e.printStackTrace();

                            }



                   }



         }



}

Hash数据结构

Hash图示

Redis中的Hashes类型可以看成具有String Key和String Value的map容器
这里写图片描述

Hash功能演示

往redis库中插入一条hash类型的数据


redis> HSET  key  field  value

举例:

redis 127.0.0.1:6379> hset user001:zhangsan  iphone 6

(integer) 1

redis 127.0.0.1:6379> hset user001:zhangsan   xiaomi 7

(integer) 1

redis 127.0.0.1:6379> hset user001:zhangsan   meizu 8

(integer) 1

在redis库中就形成了这样一条数据:
这里写图片描述

从redis库中获取一条hash类型数据的value

取出一条hash类型数据中所有field-value对

redis 127.0.0.1:6379> hgetall user001:zhangsan

1) "iphone"

2) "6"

3) "xiaomi"

4) "7"

5) "meizu"

6) "8"

取出hash数据中所有fields

redis 127.0.0.1:6379> HKEYS user001:zhangsan

1) "iphone"

2) "xiaomi"

3) "meizu"

取出hash数据中所有的value

redis 127.0.0.1:6379> hvals user001:zhangsan

1) "6"

2) "7"

3) "8"

取出hash数据中一个指定field的值

redis 127.0.0.1:6379> hget user001:zhangsan xiaomi

"8"

为hash数据中指定的一个field的值进行增减

redis 127.0.0.1:6379> HINCRBY user001:zhangsan xiaomi 1

(integer) 8

从hash数据中删除一个字段field及其值

redis 127.0.0.1:6379> hgetall user001:zhangsan

1) "iphone"

2) "6"

3) "xiaomi"

4) "7"

5) "meizu"

6) "8"

redis 127.0.0.1:6379> HDEL user001:zhangsan iphone

(integer) 1

redis 127.0.0.1:6379> hgetall user001:zhangsan

1) "xiaomi"

2) "7"

3) "meizu"

4) "8"

Set数据结构功能

集合的特点:无序、无重复元素

插入一条set数据

redis 127.0.0.1:6379> sadd frieds:zhangsan  bingbing baby fengjie furong ruhua tingting

(integer) 6

redis 127.0.0.1:6379> scard frieds:zhangsan

(integer) 6

redis 127.0.0.1:6379>

获取一条set数据的所有members

redis 127.0.0.1:6379> smembers frieds:zhangsan

1) "fengjie"

2) "baby"

3) "furong"

4) "bingbing"

5) "tingting"

6) "ruhua"

判断一个成员是否属于某条指定的set数据

redis 127.0.0.1:6379> sismember frieds:zhangsan liuyifei     #如果不是,则返回0

(integer) 0

redis 127.0.0.1:6379> sismember frieds:zhangsan baby       #如果是,则返回1

(integer) 1

求两个set数据的差集

#求差集

redis 127.0.0.1:6379> sdiff  frieds:zhangsan  friends:xiaotao

1) "furong"

2) "fengjie"

3) "ruhua"

4) "feifei"

#求差集,并将结果存入到另一个set

redis 127.0.0.1:6379> sdiffstore zhangsan-xiaotao frieds:zhangsan friends:xiaotao

(integer) 4

#查看差集结果

redis 127.0.0.1:6379> smembers zhangsan-xiaotao

1) "furong"

2) "fengjie"

3) "ruhua"

4) "feifei"

求交集,求并集

#求交集

redis 127.0.0.1:6379> sinterstore zhangsan:xiaotao frieds:zhangsan friends:xiaotao

(integer) 2

redis 127.0.0.1:6379> smembers zhangsan:xiaotao

1) "bingbing"

2) "baby"



#求并集

redis 127.0.0.1:6379> sunion  frieds:zhangsan friends:xiaotao

 1) "fengjie"

 2) "tangwei"

 3) "liuyifei"

 4) "bingbing"

 5) "ruhua"

 6) "feifei"

 7) "baby"

 8) "songhuiqiao"

 9) "furong"

10) "yangmi"

sortedSet(有序集合)数据结构

sortedSet图示

sortedset中存储的成员都有一个附带的分数值

而redis就可以根据分数来对成员进行各种排序(正序、倒序)
sortedSet存储内容示意图:
这里写图片描述

SortedSet功能演示

往redis库中插入一条sortedset数据

redis 127.0.0.1:6379> zadd nansheng:yanzhi:bang  70 liudehua  90 huangbo  100 weixiaobao  250 yangwei  59 xiaotao

(integer) 5

从sortedset中查询有序结果

#正序结果

redis 127.0.0.1:6379> zrange nanshen:yanzhi:bang  0  4

1) "xiaotao"

2) "liudehua"

3) "huangbo"

4) "weixiaobao"

5) "yangwei"

#倒序结果

redis 127.0.0.1:6379> zrevrange nanshen:yanzhi:bang 0 4

1) "yangwei"

2) "weixiaobao"

3) "huangbo"

4) "liudehua"

5) "xiaotao"

查询某个成员的名次

#在正序榜中的名次

redis 127.0.0.1:6379> zrank nanshen:yanzhi:bang  xiaotao

(integer) 0



#在倒序榜中的名次

redis 127.0.0.1:6379> zrevrank nanshen:yanzhi:bang xiaotao

(integer) 4

修改成员的分数

redis 127.0.0.1:6379> zincrby nanshen:yanzhi:bang  300  xiaotao

"359"

redis 127.0.0.1:6379> zrevrank nanshen:yanzhi:bang xiaotao

(integer) 0

Redis应用案例(1)

案例:

Lol盒子英雄数据排行榜:

1、 在redis中需要一个榜单所对应的sortedset数据

2、 玩家每选择一个英雄打一场游戏,就对sortedset数据的相应的英雄分数+1

3、 Lol盒子上查看榜单时,就调用zrange来看榜单中的排序结果

Redis应用案例(2)

实现步骤:

1、 每来一个用户创建购物车,就对购物车中的每一件商品在redis中插入一条以商品名称为key的sortedset,成员为同时出现在购物车中的其他商品,分数为1

2、 每新产生一个购物车,就对车中的商品更新redis中的sortedset,将同时出现的商品的分数增1

3、 推荐时,用户放入一件商品到购物车,则从这件商品对应的sortedset中查询分数最高的同现商品,推荐给该用户。

这里写图片描述

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值