本系列教程内容提要

Java工程师之Redis实战系列教程教程是一个学习教程,是关于Java工程师的Redis知识的实战系列教程,本系列教程均以解决特定问题为目标,使用Redis快速解决在实际生产中的相关问题,为了更方便的与大家一起探讨与学习,每个章节均提供尽可能详细的示例源码及注释,所有示例源码均可在javacourse-redis-in-action找到相关帮助!

你思考过这个问题吗?

如果你想过自己开发一个论坛网站,或者文章网站?最起码想过开发自己的博客网站吧?那么你是否考虑过这个问题--“当你数据库查询你的记录时,你考虑过这些记录应当以什么样的方式展现在网页?按发布时间?按浏览次数?

  • 按发布时间(嗯,应当时没问题的...)
  • 按浏览次数(嗯,如果给定一个时间范围也是没问题的...)

你是否浏览过stackoverflow,如下图所示,你是否考虑过这些记录时按照什么展现的呢?唔...经过你的长久思考后,你想“应该不是最新,也不是浏览最多,应该时经过一系列的机制后算出来的....”

我们通过什么机制进行排序呢?

既然你能想到一定是经过一系列的运算过程的出来的排序过程,那么我们可否设计一个符合我们自己网站的 "运算过程" 呢? 我们规定:

  • 文章的发布时间+A支持票乘以常量E-B反对票乘以常量E
  • 文章7天后不再支持投支持票/反对票

设计Redis表结构

表名 结构
文章 HASH
投票人 SET
群组 SET
文章评分排行 ZSET
文章最新排行 ZSET
群组最新文章 ZSET
群组评分排行 ZSET

核心源码

查询文章 (查询功能做的最多的就是拼装数据,但是在查询某个群组的文章的时候,就是涉及到了Redis的交集运算)

  1. /**
  2. * 获得所有文章列表文章列表
  3. *
  4. * @param page 页数
  5. * @param order 排序
  6. * @param model 模型
  7. * @return
  8. */
  9. @GetMapping(value = "/getArticleList")
  10. public String getArticle(@RequestParam(required = false, defaultValue = "1") Integer page, @RequestParam(required = false, defaultValue = "score") String order, Model model) {
  11. /*获取文章列表*/
  12. List<Article> articleArrayList = getArticles(jedis, page, order + ":");
  13. /*拼装分页信息*/
  14. model.addAttribute("articleArrayList", articleArrayList);
  15. model.addAttribute("order", order);
  16. model.addAttribute("page", page);
  17. return "index";
  18. }
  1. /**
  2. * 获取分组文章列表
  3. *
  4. * @return
  5. */
  6. @GetMapping(value = "/getGroupArticleList")
  7. public String getGroupArticle(@RequestParam(required = false, defaultValue = "1") Integer page,
  8. @RequestParam(required = false, defaultValue = "score") String order,
  9. @RequestParam(required = true) String group, Model model) {
  10. List<Article> groupArticles = getGroupArticles(jedis, group, page, order + ":");
  11. /*拼装分页信息*/
  12. model.addAttribute("groupArticles", groupArticles);
  13. model.addAttribute("group", group);
  14. model.addAttribute("order", order);
  15. model.addAttribute("page", page);
  16. return "group";
  17. }

发布文章 (发布文章需要注意的是根据文章的所属群组,将其添加至相关群组)

  1. /**
  2. * 发布文章
  3. *
  4. * @param article
  5. * @param model
  6. * @return
  7. */
  8. @PostMapping(value = "/addArticle")
  9. public String addArticle(Article article, Model model) {
  10. /*模拟用户*/
  11. User user = getUser();
  12. /*从Redis获取文章的自增ID*/
  13. String id = String.valueOf(jedis.incr("article:"));
  14. /*将文章的发帖人本人添加至投票列表*/
  15. String voted = "voted:" + id;
  16. jedis.sadd(voted, user.getUserId().toString());
  17. jedis.expire(voted, ONE_WEEK_IN_SECONDS);
  18. /*将文章添加至文章列表*/
  19. long now = System.currentTimeMillis() / 1000;
  20. String articleId = "article:" + id;
  21. HashMap<String, String> articleData = new HashMap<>();
  22. articleData.put("title", article.getTitle());
  23. articleData.put("link", article.getLink());
  24. articleData.put("user", user.getUserId().toString());
  25. articleData.put("time", String.valueOf(now));
  26. articleData.put("votes", "1");
  27. articleData.put("group", article.getGroup());
  28. articleData.put("opposeVotes", "0");
  29. jedis.hmset(articleId, articleData);
  30. /*将文章添加至分值列表*/
  31. jedis.zadd("score:", now + VOTE_SCORE, articleId);
  32. /*将文章添加至发布时间列表*/
  33. jedis.zadd("time:", now, articleId);
  34. /*将文章加入其所属分组*/
  35. addGroup(jedis, articleId, new String[]{article.getGroup()});
  36. /*设置模型数据*/
  37. model.addAttribute("page", 1);
  38. model.addAttribute("order", "score");
  39. return "redirect:/article/getArticleList";
  40. }

投票 (根据我们前面的规定,7天后不再提供对该文章的投票功能,所以需要在进行投票之前注意文章的发布时间)

  1. /**
  2. * 投票
  3. *
  4. * @param articleId
  5. * @param model
  6. * @return
  7. */
  8. @GetMapping(value = "/articleVote")
  9. public String articleVote(Integer articleId, int tag, RedirectAttributes model) {
  10. /*模拟用户*/
  11. User user = getUser();
  12. String result = article_vote(jedis, user, articleId, tag);
  13. /*设置模型数据*/
  14. model.addFlashAttribute("result", result);
  15. model.addFlashAttribute("page", 1);
  16. model.addFlashAttribute("order", "score");
  17. return "redirect:/article/getArticleList";
  18. }

运行效果图

各位友友可以下载本章的示例源码,运行访问 http://localhost:8080/article/getArticleList



本章源码提供完整的运行环境源码GitHub下载

Redis构建文章聚合信息分类网站的更多相关文章

  1. 使用Redis构建文章投票网站

    涉及到的key: 1. article_time, 记录文章的发布时间,zset结构 2. article_score, 记录文章的得分, zset结构 得分 = 发布时间 + 投票用户数 X 432 ...

  2. 使用redis构建文章投票系统

    首先,我得说明这篇博客基本上就是<<redis in action>>第一章内容的读书笔记. 需求 首先,说明一下,我们的需求 用户可以发表文章,发表时,自己就默认的给自己的文 ...

  3. redis 实例2 构建文章投票网站后端

    redis 实例2 构建文章投票网站后端   1.限制条件 一.如果网站获得200张支持票,那么这篇文章被设置成有趣的文章 二.如果网站发布的文章中有一定数量被认定为有趣的文章,那么这些文章需要被设置 ...

  4. redis实战笔记(6)-第6章 使用 Redis构建应用程序组件

    本章主要内容   1.构建两个前缀匹配自 动补全程序 2.通过构建分布式锁来提高性能 3.通过开发计数信号量来控制并发 4.构建两个不同用途的任务队列 5.通过消息拉取系统来实现延迟消息传递 6.学习 ...

  5. redis实战笔记(2)-第2章 使用 Redis构建Web应用

    第2章 使用 Redis构建Web应用 本章主要内容   1.登录cookie 2.购物车cookie 3.缓存生成的网页 4.缓存数据库行 5.分析网页访问记录   本章的所有内容都是围绕着发现并解 ...

  6. 《Redis官方文档》用Redis构建分布式锁

    用Redis构建分布式锁 在不同进程需要互斥地访问共享资源时,分布式锁是一种非常有用的技术手段. 有很多三方库和文章描述如何用Redis实现一个分布式锁管理器,但是这些库实现的方式差别很大,而且很多简 ...

  7. Redis系列文章-数据结构篇

    Redis系列文章 前言: 工作原因,在学习mybatis知识后,2个月没有补充新的知识了,最近拿起书本开始学习.打算写下这个Redis系列的文章. 目录结构如下: Redis内置数据结构 Redis ...

  8. 七、Abp vNext 基础篇丨文章聚合功能下

    介绍 不好意思这篇文章应该早点更新的,这几天在忙CICD的东西没顾得上,等后面整好了CICD我也发2篇文章讲讲,咱们进入正题,这一章来补全剩下的 2个接口和将文章聚合进行完善. 开工 上一章大部分业务 ...

  9. nginx+lua+redis构建高并发应用(转)

    nginx+lua+redis构建高并发应用 ngx_lua将lua嵌入到nginx,让nginx执行lua脚本,高并发,非阻塞的处理各种请求. url请求nginx服务器,然后lua查询redis, ...

随机推荐

  1. Python:基本运算、基本函数(包括复数)、Math模块、NumPy模块

    基本运算 x**2 : x^2 若x是mat矩阵,那就表示x内每个元素求平方 inf:表示正无穷 逻辑运算符:and,or,not 字典的get方法 a.get(k,d) 1 1 get相当于一条if ...

  2. UML总结---UML中的事物和关系

    UML中的事物 名称 说明 图形 类 相同属性方法的集合 接口 类或组件提供的,可以完成特定功能的一组操作的集合 协作 合作的动作 用例 系统的一个功能 节点 代表可计算的资源 活动类 有多个线程的类 ...

  3. Qt 反射

    简介 本文主要讲解Qt是如何实现反射,以及一点点反射使用的小心得. 文章概览 Qt反射内幕小窥 详细内容 反射前期准备 得到注册的类成员变量 得到注册的类成员函数 访问类成员属性(get,set) 调 ...

  4. struts2-Action配置-通配符-DMI

    1. ActionMethod: Action执行的时候并不一定要执行execute方法,有两种替换办法如下: ①在配置文件中配置action的时候用“method”属性来指定执行哪个方法 ②在url ...

  5. hibernate、struts、spring mvc的作用

    Hibernate工作原理及为什么要用?原理:1.读取并解析配置文件2.读取并解析映射信息,创建SessionFactory3.打开Sesssion4.创建事务Transation5.持久化操作6.提 ...

  6. 常用HQL(Hibernate Query Language)查询

    查询一个对象(实体类必须有一个不带参数的构造方法) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Test public void test01() ...

  7. 在hibernate中查询单个对象的方法,get()、load()、

    查询单个对象可以直接通过Session对象来做到,其中session这个对象提过了2种获得单个对象的方法,一个是get方法和load方法,我去看这个两个方法的时候发现这两个方法的参数是一样的,使用方式 ...

  8. Java 关于finally、static

    论坛上看到的两道题目,如下: //为啥运行结果是1 0 不是 0 0呢 谁能解释下啊 public class FinallyDemo { static int value = 0; static i ...

  9. Jquery实用代码片段(转)

    1.把所有带有#的空链接换成不友情的链接 $('a[href="#"]').each(function() { $(this).attr('href', 'javascript:v ...

  10. JavaSE(八)集合之List

    前面一篇的corejava讲的是集合的概述,这一篇我将详细的和大家讲解一下Collection下面的List.set.queue这三个子接口.希望大家能得到提升. 一.List接口 1.1.List接 ...