• Redis从基础命令到实战之列表类型(List)


    经过上一篇基于Redis散列类型的改造后,实战练习中的商品管理已经具备了增加、修改整体、修改部分属性和分页查询功能,但仍然不支持删除商品的功能。这是因为商品总数是以一个自增数字记录的,且关联了新商品key的生成,删除商品后不能直接减小总数,进而会影响到分页的计算。

    在本节中将完善这个功能,使用一个新的数据类型 - 列表类型(List)来保存所有商品ID,计算商品总量时通过计算列表类型长度获得,删除商品时也同时删除列表中的ID。

    列表类型用于存储可重复的字符串列表,内部按照添加的先后保持顺序,在列表两端添加和取出元素非常高效,常见的应用场景是社交网站取出最新发表内容列表,也可以用于实现消息队列。先看常用的操作。

    一、常用命令

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. import java.util.List;  
    2.   
    3. import redis.clients.jedis.Jedis;  
    4. import redis.clients.jedis.SortingParams;  
    5. import redis.clients.jedis.BinaryClient.LIST_POSITION;  
    6.   
    7. public class ListExample {  
    8.   
    9.     public static void main(String[] args) {  
    10.         Jedis jedis = JedisProvider.getJedis();  
    11.         jedis.flushDB();  
    12.           
    13.         //lpush 在左边添加  
    14.         String fruitKey = "fruit";  
    15.         long lpush = jedis.lpush(fruitKey, "apple");  
    16.         print("lpush " + fruitKey + " apple=" + lpush);  
    17.         lpush = jedis.lpush(fruitKey, "banana");  
    18.         print("lpush " + fruitKey + " banana=" + lpush);  
    19.         jedis.lpush(fruitKey, "apple");  
    20.         jedis.lpush(fruitKey, "apple");  
    21.         jedis.lpush(fruitKey, "orange");  
    22.         jedis.lpush(fruitKey, "grape");  
    23.         jedis.lpush(fruitKey, "peach");  
    24.         jedis.lpush(fruitKey, "lemon");  
    25.           
    26.         //rpush 在右边添加  
    27.         String numberKey = "numbers";  
    28.         jedis.rpush(numberKey, "5");  
    29.         jedis.rpush(numberKey, "4");  
    30.         jedis.rpush(numberKey, "2");  
    31.         jedis.rpush(numberKey, "1");  
    32.           
    33.         //lrange 获得列表片段  
    34.         print("lrange " + fruitKey + " [0,-1]=" + jedis.lrange(fruitKey, 0, -1));  
    35.         print("lrange " + numberKey + " [0,-1]=" + jedis.lrange(numberKey, 0, -1));  
    36.         print("lrange " + fruitKey + " [1,3]=" + jedis.lrange(fruitKey, 1, 3));  
    37.           
    38.         //删除列表指定的值,第二个参数为删除的个数(有重复时),后添加进去的值先被删,类似于出栈,返回删除个数  
    39.         Long del = jedis.lrem(fruitKey, 2, "apple");  
    40.         print("lrem " + fruitKey + " apple*2=" + del);  
    41.         print("after lrem, lrange " + fruitKey + " [0,-1]=" + jedis.lrange(fruitKey, 0, -1));  
    42.           
    43.         //删除区间以外的数据, 成功返回 OK  
    44.         String ltrim = jedis.ltrim(fruitKey, 0, 3);  
    45.         print("ltrim " + fruitKey + " [0,3]=" + ltrim);  
    46.         print("after ltrim, lrange " + fruitKey + " [0,-1]=" + jedis.lrange(fruitKey, 0, -1));  
    47.           
    48.         //列表元素出栈  
    49.         String lpop = jedis.lpop(fruitKey);  
    50.         print("lpop " + fruitKey + " =" + lpop);  
    51.         print("after lpop, lrange " + fruitKey + " [0,-1]=" + jedis.lrange(fruitKey, 0, -1));  
    52.           
    53.         //修改列表中指定下标的值   
    54.         String lset = jedis.lset(fruitKey, 0, "mango");  
    55.         print("lset " + fruitKey + " 0=" + lset);  
    56.         print("after lset, lrange " + fruitKey + " [0,-1]=" + jedis.lrange(fruitKey, 0, -1));  
    57.           
    58.         //数组长度  
    59.         print("llen " + fruitKey + " =" + jedis.llen(fruitKey));  
    60.           
    61.         //排序  
    62.         SortingParams sortingParameters = new SortingParams();  
    63.         sortingParameters.alpha();  
    64.         sortingParameters.limit(0, 3);  
    65.         List<String> list = jedis.sort(fruitKey, sortingParameters);  
    66.         String sort = "";  
    67.         for(int i = 0; i < list.size(); i++) {  
    68.             sort += list.get(i) + " ";  
    69.         }  
    70.         print("sort " + fruitKey + " =" + sort);  
    71.           
    72.         //获取列表指定下标的值, 不存在返回null  
    73.         int pos = 2;  
    74.         String lindex = jedis.lindex(fruitKey, pos);  
    75.         print("lindex " + fruitKey + " 2=" + lindex);  
    76.           
    77.         //在指定元素前/后插入  
    78.         jedis.linsert(numberKey, LIST_POSITION.BEFORE, "2", "3");  
    79.         print("after linsert, lrange " + numberKey + " [0,-1]=" + jedis.lrange(numberKey, 0, -1));  
    80.           
    81.         String value = jedis.rpoplpush(numberKey, "dst");  
    82.         while(value != null) {  
    83.             System.out.println("rpoplpush " + numberKey + " =" + value);  
    84.             value = jedis.rpoplpush(numberKey, "dst");  
    85.         }  
    86.         print("after rpoplpush, lrange dst [0,-1]=" + jedis.lrange("dst", 0, -1));  
    87.           
    88.         jedis.close();  
    89.     }  
    90.   
    91.     private static void print(String info) {  
    92.         System.out.println(info);  
    93.         System.out.println("------------------------------------------------------");  
    94.         System.out.println();  
    95.     }  
    96. }  

    二、实践练习

    在上一篇商品管理示例的基础上,增加删除商品的功能。

    修改添加商品的功能代码,增加了列表类型保存所有新加入的商品ID

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. /** 
    2.  * 添加一个商品 
    3.  * @param goods 
    4.  * @return 
    5.  */  
    6. public boolean addGoods(Goods goods) {  
    7.     long id = getIncrementId();  
    8.     Map<String, String> map = new HashMap<>();  
    9.     map.put("id", String.valueOf(id));  
    10.     map.put("title", goods.getTitle());  
    11.     map.put("price", String.valueOf(goods.getPrice()));  
    12.     String key = "goods:" + id;  
    13.     boolean added = jedis.hmset(key, map).equals("OK");  
    14.     if(added) {  
    15.         jedis.rpush("goods:list", String.valueOf(id));  
    16.     }  
    17.     return added;  
    18. }  

    添加删除商品功能代码

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. /** 
    2.  * 删除商品 
    3.  * @param id 
    4.  * @return 
    5.  */  
    6. public boolean delGoods(long id) {  
    7.     long deleted = jedis.del("goods:" + id);  
    8.     if(deleted == 1) {  
    9.         jedis.lrem("goods:list", 1, String.valueOf(id));  
    10.     }  
    11.     return deleted == 1;  
    12. }  

    还需要修改获得商品总数和分页查询商品的代码,商品总数和ID列表改为从goods:list中获得

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. /** 
    2.  * 读取商品总数 
    3.  * @return 
    4.  */  
    5. public long getTotalCount() {  
    6.     String key = "goods:list";  
    7.     return jedis.llen(key);  
    8. }  
    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. /** 
    2.  * 读取用于分页的商品列表 
    3.  * @param pageIndex 页数 
    4.  * @param pageSize 每页显示行数 
    5.  * @return 
    6.  */  
    7. public List<Goods> getGoodsList(int pageIndex, int pageSize) {  
    8.     int totals = (int)getTotalCount();  
    9.     int from = (pageIndex - 1) * pageSize;  
    10.     if(from < 0) {  
    11.         from = 0;  
    12.     }  
    13.     else if(from > totals) {  
    14.         from = (totals / pageSize) * pageSize;  
    15.     }  
    16.     int to = from + pageSize - 1;  
    17.     if(to > totals) {  
    18.         to = totals;  
    19.     }  
    20.     List<Goods> goodsList = new ArrayList<>();  
    21.     List<String> idList = jedis.lrange("goods:list", from, to);  
    22.     for(String id : idList) {  
    23.         String key = "goods:" + id;  
    24.         Map<String, String> maps = jedis.hgetAll(key);  
    25.         Goods goods = new Goods();  
    26.         goods.setId(NumberUtils.toLong(maps.get("id")));  
    27.         goods.setTitle(maps.get("title"));  
    28.         goods.setPrice(NumberUtils.toFloat(maps.get("price")));  
    29.         goodsList.add(goods);  
    30.     }  
    31.     return goodsList;  
    32. }  

    测试代码

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. public static void main(String[] args) {  
    2.     ListLession ll = new ListLession();  
    3.     ll.clear();  
    4.       
    5.     //添加一批商品  
    6.     for(int i = 0; i< 42; i++) {  
    7.         Goods goods = new Goods(0, "goods" + String.format("%05d", (i + 1)), i);  
    8.         ll.addGoods(goods);  
    9.     }  
    10.     //读取商品总数  
    11.     System.out.println("商品总数: " + ll.getTotalCount());  
    12.     //删除第29件商品  
    13.     ll.delGoods(29);  
    14.     System.out.println("删除后商品总数: " + ll.getTotalCount());  
    15.     //分页显示  
    16.     List<Goods> list = ll.getGoodsList(2, 20);  
    17.     System.out.println("第二页商品:");  
    18.     for(Goods goods : list) {  
    19.         System.out.println(goods);  
    20.     }  
    21. }  

    现在,商品管理已经具备了增删改查功能,但是Redis还有两个数据类型没有被使用到,下一节将使用集合类型来实现为商品添加分类的功能。

    源码下载

  • 相关阅读:
    【每日英语】
    【百宝箱】CLion: Cound not load cache
    C# WPF:这次把文件拖出去!
    C# WPF:快把文件从桌面拖进我的窗体来!
    两个List< string>比较是否相同的N种方法,你用过哪种?
    分享套接字数据包序列化与反序列化方法
    如何从含有占位符的字符串生成一个ReactNode数组
    vscode 插件配置指北
    第十一周总结
    机场&代理商-关系图
  • 原文地址:https://www.cnblogs.com/sa-dan/p/6836880.html
Copyright © 2020-2023  润新知