美文网首页小程序
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