美文网首页小程序
springboot+jpa+redis+quzartz+ela

springboot+jpa+redis+quzartz+ela

作者: I讨厌鬼I | 来源:发表于2019-07-20 21:16 被阅读0次

    点赞模块

    点赞模块主要分为两部分,点赞信息的更新和查看是否点赞,收藏和关注也是如此,首先是点赞信息的更新

    点赞更新

    点赞更新需要拿到对应的点赞信息和帖子信息,帖子信息用于增加点赞数,如果没有点赞信息还需要新建点赞信息,并且发一个消息通知被点赞的用户,消息我简单的使用一个数据库表来实现的,比较low,如果有点赞信息就直接拿来更新,同时根据更新前的状态来更新帖子的点赞数,点赞数用redis的自增操作来保证原子性,更新完后把点赞信息进行保存。

    @Override
        /**
         * 帖子点赞更新
         */
        public LikeArticle updateLikeArticle(LikeArticleForm likeArticleForm, String userId) throws BBSException {
            LikeArticle likeArticle;
            String articleId = likeArticleForm.getLikeArticleId();
            // 1.在redis或数据库中查找被点赞的帖子
            Article article = articleService.getArticle(articleId);
            // 2.看redis中有没有帖子点赞信息
            if (redisTemplate.hasKey("LikeArticle::" + articleId + '-' + userId)){
                likeArticle = (LikeArticle) redisTemplate.opsForValue().get("LikeArticle::" + articleId + '-' + userId);
            }
            // 3.若没有则去数据库中查询点赞信息
            else {
                likeArticle = likeArticleRepository.findLikeArticle(articleId, userId);
            }
            // 4.若还是没有则新建点赞信息,并设置帖子id和点赞用户id
            if (likeArticle == null){
                likeArticle = new LikeArticle();
                likeArticle.setLikeArticleId(articleId);
                likeArticle.setLikeUserId(userId);
                // 如果是新建的点赞信息,并且点赞的状态是已点赞,而且点赞的不是自己的帖子,则创建新的点赞通知消息
                if (likeArticleForm.getIsLike().equals(LikeEnum.LIKE.getCode())
                        && !userId.equals(article.getArticleUserId())){
                    Message message = new Message();
                    message.setArticleId(articleId);
                    message.setMessageType(MessageEnum.LIKE_MESSAGE.getCode());
                    message.setReceiverUserId(article.getArticleUserId());
                    message.setSenderUserId(userId);
                    message.setRepliedContent(article.getArticleContent());
                    message.setMessageContent("赞了你的帖子");
                    messageService.createMessage(message);
                }
            }
            // 5.更新被点赞帖子的点赞数
            // 如果点赞信息为空或者为未点赞且要更新的点赞信息为已点赞,则帖子点赞数+1
            if (likeArticle.getIsLike() == null || likeArticle.getIsLike().equals(LikeEnum.NOT_LIKE.getCode())){
                if (likeArticleForm.getIsLike() == LikeEnum.LIKE.getCode()){
                    redisTemplate.opsForHash().increment("Article::" + articleId, "articleLikeNum", 1);
                }
            }
            // 如果点赞信息为已点赞且要更新的点赞信息为未点赞,则帖子点赞数-1
            else {
                if (likeArticleForm.getIsLike().equals(LikeEnum.NOT_LIKE.getCode())){
                    redisTemplate.opsForHash().increment("Article::" + articleId, "articleLikeNum", -1);
                }
            }
            // 5.设置点赞状态
            likeArticle.setIsLike(likeArticleForm.getIsLike());
            // 6.将点赞信息存入redis
            redisTemplate.opsForValue().set("LikeArticle::" + articleId + '-' + userId, likeArticle, 1, TimeUnit.HOURS);
            return likeArticle;
        }
    

    查看是否点赞过

    这步比较简单,直接拿出来看看,返回truefalse就可以:

    @Override
        /**
         * 查看帖子是否被点赞
         */
        public Boolean isArticleLike(String articleId, String userId) {
            LikeArticle likeArticle;
            if (redisTemplate.hasKey("LikeArticle::" + articleId + '-' + userId)){
                likeArticle = (LikeArticle) redisTemplate.opsForValue().get("LikeArticle::" + articleId + '-' + userId);
            }
            else {
                likeArticle = likeArticleRepository.findLikeArticle(articleId, userId);
            }
            if (likeArticle != null){
                redisTemplate.opsForValue().set("LikeArticle::" + articleId + '-' + userId, likeArticle, 1, TimeUnit.HOURS);
                return likeArticle.getIsLike().equals(LikeEnum.LIKE.getCode());
            }
            else return false;
        }
    

    更新点赞信息到数据库

    同样使用定时任务进行更新,这里只提供一个方法。

    @Override
        /**
         * 从redis更新帖子点赞到数据库
         */
        @Transactional
        public void updateLikeArticleDatabase() {
            // 1.找到所有有关收藏的key
            Set<String> likeArticleKeys = redisTemplate.keys("LikeArticle::*");
            // 2.保存数据到数据库并清除redis中数据
            for (String likeArticleKey : likeArticleKeys){
                LikeArticle likeArticle = (LikeArticle) redisTemplate.opsForValue().get(likeArticleKey);
                likeArticle = likeArticleRepository.save(likeArticle);
                // 注意redis中的数据没有主键,必须存一次数据库有了主键后再存redis
                redisTemplate.opsForValue().set(likeArticleKey, likeArticle, redisTemplate.getExpire(likeArticleKey), TimeUnit.SECONDS);
    //            redisTemplate.delete(likeArticleKey);
            }
            return;
        }
    

    定时任务

    使用Quartz作为定时任务的框架

    pom.xml

    引入依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-quartz</artifactId>
    </dependency>
    

    Quartz配置类

    @Configuration
    public class QuartzConfig {
    
        private static final String BBS_TASK_IDENTITY = "BBSTaskQuartz";
    
        @Bean
        public JobDetail quartzDetail(){
            return JobBuilder.newJob(BBSTask.class).withIdentity(BBS_TASK_IDENTITY).storeDurably().build();
        }
    
        @Bean
        public Trigger quartzTrigger(){
            SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
    //                .withIntervalInSeconds(10)  //设置时间周期单位秒
                      .withIntervalInSeconds(15)//15秒执行一次
                    .repeatForever();
            return TriggerBuilder.newTrigger().forJob(quartzDetail())
                    .withIdentity(BBS_TASK_IDENTITY)
                    .withSchedule(scheduleBuilder)
                    .build();
        }
    }
    

    使用定时任务

    新建一个叫task的包,建一个BBSTask类来进行定时任务,里面调用帖子、评论、点赞、收藏、关注等有关缓存更新到数据库的方法:

    @Slf4j
    public class BBSTask extends QuartzJobBean {
    
        @Autowired
        private ArticleServiceImpl articleService;
    
        @Autowired
        private CommentServiceImpl commentService;
    
        @Autowired
        private LikeServiceImpl likeService;
    
        @Autowired
        private CollectServiceImpl collectService;
    
        @Autowired
        private AttentionServiceImpl attentionService;
    
        private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
        @Override
        protected void executeInternal(JobExecutionContext jobExecutionContext) {
    
            log.info("BBSTask-------- {}", sdf.format(new Date()));
            articleService.updateArticleDatabase();
            commentService.updateCommentDatabase();
            likeService.updateLikeArticleDatabase();
            likeService.updateLikeCommentDatabase();
            collectService.updateCollectDatabase();
            attentionService.updateAttentionDatabase();
        }
    }
    

    Quartz了解不太多,可能有什么写的不好的,欢迎批评指正。
    到这里,小程序的整个项目就说的差不多了,第一次写这样的文章不太有经验,有些地方可能说的不太清楚,详细的项目源码可以移步github桂香驿站
    上一篇:springboot+jpa+redis+quzartz+elasticsearch实现微信论坛小程序(四)

    相关文章

      网友评论

        本文标题:springboot+jpa+redis+quzartz+ela

        本文链接:https://www.haomeiwen.com/subject/igxplctx.html