SpringBoot实现文章点赞功能

提示:今日是2024年的6月30日,未来的你看到这篇文章,希望你依旧快乐

文章目录


前言

首先在这里前缀部分我就不做要求了,比如说登录信息什么的


数据库表格

这里实现点赞功能,主要是围绕论坛项目完成的

user_info代表用户信息表

forum_article代表着文章信息表

user_message代表着点赞或者评论点赞发送信息表

like_record代表着用户点赞表

 user_info用户信息表

 

 forum_article文章信息表

 

 user_message点赞评论信息发送表

 

 

 like_record点赞信息表

 

 

 表格准备完毕

代码实现

Controller层

 

/**
     * 实现文章点赞功能。
     * 通过请求映射 "/doLike",该方法处理用户对文章的点赞操作。
     * 使用@GlobalInterceptor注解,表明该方法受全局拦截器影响,会检查参数有效性及用户登录状态。
     *
     * @param session 用户会话对象,用于获取会话中的用户信息。
     * @param articleId 需要点赞的文章ID,通过@VerifyParam注解确保其为非空,保证操作的有效性。
     * @return 返回操作成功的响应对象。
     */
    @RequestMapping("/doLike")
    @GlobalInterceptor(checkParams = true, checkLogin = true)
    public ResponseVO likeArticle(HttpSession session, @VerifyParam(required = true) String articleId) {
        // 从会话中获取用户信息
        SessionWebUserDto sessionWebUserDto = getUserInfoFromSession(session);
        // 调用点赞服务,记录用户的点赞行为
        likeRecordService.doLike(articleId, sessionWebUserDto.getUserId(), sessionWebUserDto.getNickName(), OperRecordOpTypeEnum.ARTICLE_LIKE);
        // 返回操作成功的响应
        return getSuccessResponseVO(null);
    }
//枚举

package com.easybbs.entity.enums;

public enum OperRecordOpTypeEnum {
    ARTICLE_LIKE(0, "文章点赞"),
    COMMENT_LIKE(1, "评论点赞");


    private Integer type;
    private String desc;

    OperRecordOpTypeEnum(Integer type, String desc) {
        this.type = type;
        this.desc = desc;
    }

    public Integer getType() {
        return type;
    }

    public String getDesc() {
        return desc;
    }

}

至于这里的参数校验和登录校验我就不作详细解释了,相信未来的你也一定可以看懂

 Service接口层

//点赞
	void doLike(String objectId, String userId, String nickName, OperRecordOpTypeEnum opTypeEnum);

 Service接口实现层

/**
	 * 用户点赞操作。
	 * 实现对文章或评论的点赞功能,并记录用户的点赞行为。
	 * @param objectId 点赞对象的ID,可以是文章ID或评论ID。
	 * @param userId 点赞用户的ID。
	 * @param nickName 点赞用户的昵称。
	 * @param opTypeEnum 点赞操作的类型,区分是文章点赞还是评论点赞。
	 * @throws BusinessException 如果文章不存在,则抛出业务异常。
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void doLike(String objectId, String userId, String nickName, OperRecordOpTypeEnum opTypeEnum) {
	    // 创建用户消息对象,用于记录点赞行为。
	    UserMessage userMessage = new UserMessage();
	    userMessage.setCreateTime(new Date());

	    // 根据点赞类型执行不同的操作。
	    switch (opTypeEnum){
	        case ARTICLE_LIKE:
	            // 根据文章ID查询文章信息,如果文章不存在,则抛出异常。
	            ForumArticle forumArticle = forumArticleMapper.selectByArticleId(objectId);
	            if(forumArticle == null){
	                throw new BusinessException("文章不存在");
	            }
	            // 执行文章点赞逻辑。
	            articleLike(objectId,forumArticle,userId,opTypeEnum);
	            // 设置用户消息的相关信息,如文章ID、文章标题等。
	            userMessage.setArticleId(objectId);
	            userMessage.setArticleTitle(forumArticle.getTitle());
	            userMessage.setMessageType(MessageTypeEnum.ARTICLE_LIKE.getType());
	            userMessage.setCommentId(Constants.ZERO);
	            userMessage.setReceivedUserId(forumArticle.getUserId());
	            break;
	        case COMMENT_LIKE:
	            // 评论点赞的逻辑实现。
	            break;
	    }

	    // 设置用户消息的发送者信息。
	    userMessage.setSendUserId(userId);
	    userMessage.setSendNickName(nickName);
	    userMessage.setStatus(MessageStatusEnum.NO_READ.getStatus());

	    // 判断是否为给自己的点赞,若是,则不记录点赞消息。
	    // 判断是否已经点赞
	    if(!userId.equals(userMessage.getReceivedUserId())){
	        // 根据文章ID、评论ID、发送者ID和消息类型查询是否已存在相同的点赞记录。
	        UserMessage dbInfo = userMessageMapper.selectByArticleIdAndCommentIdAndSendUserIdAndMessageType(userMessage.getArticleId(),userMessage.getCommentId()
	        ,userMessage.getSendUserId(),userMessage.getMessageType());
	        // 如果不存在相同的点赞记录,则插入新的点赞消息。
	        if(dbInfo == null ){
	            userMessageMapper.insert(userMessage);
	        }
	    }
	}

	/**
	 * 用户对文章进行点赞或取消点赞操作。
	 *
	 * @param objId 对象ID,即文章的唯一标识。
	 * @param forumArticle 文章对象,用于获取文章的作者信息。
	 * @param userId 用户ID,执行点赞操作的用户。
	 * @param opTypeEnum 操作类型枚举,表示点赞或取消点赞。
	 * @return 返回点赞记录,如果用户之前点赞过,则返回非空;否则返回空。
	 */
	public LikeRecord articleLike(String objId, ForumArticle forumArticle, String userId, OperRecordOpTypeEnum opTypeEnum) {
	    // 根据对象ID、用户ID和操作类型查询点赞记录,判断用户是否已经点赞过。
	    LikeRecord record = this.likeRecordMapper.selectByObjectIdAndUserIdAndOpType(objId, userId, opTypeEnum.getType());
	    if (record != null) {
	        // 如果用户之前点赞过,则取消点赞。
	        this.likeRecordMapper.deleteByObjectIdAndUserIdAndOpType(objId, userId, opTypeEnum.getType());
	        // 更新文章的点赞数,减少1。
	        forumArticleMapper.updateArticleCount(UpdateArticleCountTypeEnum.GOOD_COUNT.getType(), -1, objId);
	    } else {
	        // 如果用户未点赞,则创建新的点赞记录。
	        LikeRecord likeRecord = new LikeRecord();
	        likeRecord.setObjectId(objId);
	        likeRecord.setUserId(userId);
	        likeRecord.setOpType(opTypeEnum.getType());
	        likeRecord.setCreateTime(new Date());
	        // 设置点赞记录的作者用户ID为文章的作者用户ID。
	        likeRecord.setAuthorUserId(forumArticle.getUserId());
	        // 插入新的点赞记录。
	        this.likeRecordMapper.insert(likeRecord);
	        // 更新文章的点赞数,增加1。
	        forumArticleMapper.updateArticleCount(UpdateArticleCountTypeEnum.GOOD_COUNT.getType(), 1, objId);
	    }
	    // 返回点赞记录,无论是否新点赞或取消点赞。
	    return record;
	}

Mapper层

<!-- 根据PrimaryKey获取对象-->
	<select id="selectByArticleId" resultMap="base_result_map" >
		select <include refid="base_column_list" />,content,markdown_content from forum_article where article_id=#{articleId}
	</select>

<!-- 根据PrimaryKey获取对象-->
	<select id="selectByArticleIdAndCommentIdAndSendUserIdAndMessageType" resultMap="base_result_map" >
		select <include refid="base_column_list" /> from user_message where article_id=#{articleId} and comment_id=#{commentId} and send_user_id=#{sendUserId} and message_type=#{messageType}
	</select>

<!-- 根据ObjectIdAndUserIdAndOpType删除-->
	<delete id="deleteByObjectIdAndUserIdAndOpType">
		delete from like_record where object_id=#{objectId} and user_id=#{userId} and op_type=#{opType}
	</delete>

	<!-- 根据PrimaryKey获取对象-->
	<select id="selectByObjectIdAndUserIdAndOpType" resultMap="base_result_map" >
		select <include refid="base_column_list" /> from like_record where object_id=#{objectId} and user_id=#{userId} and op_type=#{opType}
	</select>

 总结

当然上面只是一些代码的展示,但其实主要的是思路,那接下来我就说明一下我实现的思路

文章点赞功能,首先文章点赞传到Controller层的时候,肯定需要把文章id传送过去,在Controller接受到文章id之后,再从登录信息里面传递出来用户的id,用户的名称,是文章点赞还是评论点赞呢,传递过去之后,创建发送消息的对象,根据点赞类型进行分开,如果是文章点赞的话,首先根据用户id,文章id,点赞类型去查找点赞的记录表,如果说找到了的话,取消点赞,实际上也就是删除点赞信息,删除一条点赞信息表里面的语句,如果说没有点赞的话,创建一个点赞对象,点赞的人是这个用户,名称是这个用户,点赞的文章是文章id,点赞的类型是文章点赞,还需要额外设置点赞是给哪一个用户点赞,肯定是根据文章信息找到发送文章的人,然后插入新的点赞记录,更改文章的点赞数,如果说取消点赞也需要更改文章点赞类型,

点赞完成之后去继续完善用户发送信息表,比如说设置文章id,文章标题,文章点赞类型,接收人用户id是谁,发送人用户id是谁,发送人名字是谁,发送的是未读状态,

接下来首先需要判断不是自己给自己点赞,自己给自己点赞是肯定不会发送消息的,如果说根据文章id,评论的id发送者id,点赞类型查找如果说没有查找到的话,添加一条记录消息,总不能每次点赞完成之后都发送一次消息吧,发送的肯定是一次消息,大概逻辑就是这样

  • 16
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring Boot整合Redis点赞功能的简单实现步骤如下: 1. 首先,需要在pom.xml文件中添加Redis和Jedis的依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3..1</version> </dependency> ``` 2. 在application.properties文件中配置Redis的连接信息: ``` spring.redis.host=localhost spring.redis.port=6379 spring.redis.password= ``` 3. 创建一个RedisUtil类,用于连接Redis并提供点赞相关的方法: ``` @Component public class RedisUtil { @Autowired private RedisTemplate<String, Object> redisTemplate; public void like(String key, String value) { redisTemplate.opsForSet().add(key, value); } public void unlike(String key, String value) { redisTemplate.opsForSet().remove(key, value); } public boolean isLiked(String key, String value) { return redisTemplate.opsForSet().isMember(key, value); } public long countLikes(String key) { return redisTemplate.opsForSet().size(key); } } ``` 4. 在Controller中使用RedisUtil提供的方法实现点赞功能: ``` @RestController public class LikeController { @Autowired private RedisUtil redisUtil; @PostMapping("/like") public void like(@RequestParam String key, @RequestParam String value) { redisUtil.like(key, value); } @PostMapping("/unlike") public void unlike(@RequestParam String key, @RequestParam String value) { redisUtil.unlike(key, value); } @GetMapping("/isLiked") public boolean isLiked(@RequestParam String key, @RequestParam String value) { return redisUtil.isLiked(key, value); } @GetMapping("/countLikes") public long countLikes(@RequestParam String key) { return redisUtil.countLikes(key); } } ``` 以上就是Spring Boot整合Redis点赞功能的简单实现。 ### 回答2: Spring Boot和Redis都是非常流行的技术,它们都可以轻松地实现各种功能,其中包括点赞功能。本篇文章主要介绍如何使用Spring Boot和Redis来实现一个简单的点赞功能。 1. 首先,我们要在pom.xml文件中添加Spring Boot的依赖,以及Jedis依赖。Jedis是一个专门与Redis交互的Java客户端,可以方便地操作Redis。 ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.6.3</version> </dependency> ``` 2. 接下来,我们要在application.properties文件中配置Redis连接信息。 ```properties spring.redis.database=0 spring.redis.host=localhost spring.redis.password= spring.redis.port=6379 ``` 3. 然后,我们要创建一个RedisTemplate实例,以便于操作Redis。 ```java @Configuration public class RedisConfig { @Bean JedisConnectionFactory jedisConnectionFactory() { return new JedisConnectionFactory(); } @Bean RedisTemplate<String, Object> redisTemplate() { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(jedisConnectionFactory()); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return redisTemplate; } } ``` 4. 接下来,我们要创建一个点赞服务实现类并注入RedisTemplate实例。 ```java @Service public class VoteServiceImpl implements VoteService { private final RedisTemplate<String, Object> redisTemplate; @Autowired public VoteServiceImpl(RedisTemplate<String, Object> redisTemplate) { this.redisTemplate = redisTemplate; } @Override public void vote(String userId, Long itemId) { String key = "vote:" + itemId; redisTemplate.opsForSet().add(key, userId); } @Override public Long count(Long itemId) { String key = "vote:" + itemId; return redisTemplate.opsForSet().size(key); } } ``` 在这个实现类中,我们创建了两个方法,vote和count,分别用来进行点赞和获取点赞数量。通过使用RedisTemplate实例的opsForSet方法,我们可以方便地对集合进行添加元素和获取元素的操作。 5. 最后,我们可以在Controller中调用这个服务类,实现点赞功能。 ```java @RestController public class VoteController { private final VoteService voteService; @Autowired public VoteController(VoteService voteService) { this.voteService = voteService; } @PostMapping("/vote") public void vote(@RequestParam String userId, @RequestParam Long itemId) { voteService.vote(userId, itemId); } @GetMapping("/count") public Long count(@RequestParam Long itemId) { return voteService.count(itemId); } } ``` 至此,我们就只需要发送一个POST请求到"/vote"路径,并附带上userId和itemId参数,就可以对该itemId进行点赞了。而发送一个GET请求到"/count"路径,并附带上itemId参数,则可以获取到该itemId的点赞数。 短短几行代码就实现点赞功能,而且使用Redis做后台存储,性能和稳定性都更好。在实际开发过程中,如果需要高并发、高可用的点赞功能,Redis就是一种非常好的选择。 ### 回答3: SpringBoot是基于Spring框架的快速开发脚手架,而Redis是著名的内存数据库,具有高性能、分布式、数据持久化等特点。在实现点赞功能时,我们常常使用Redis来存储点赞信息,以提高访问效率和减轻数据库的压力。 下面是SpringBoot整合Redis点赞功能的简单实现步骤: 1. 引入相关依赖 在pom.xml文件中添加以下依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` 2. 配置Redis连接信息 在application.properties文件中配置Redis连接信息,例如: ``` spring.redis.host=127.0.0.1 spring.redis.port=6379 ``` 3. 创建Redis操作类 创建一个RedisUtil类,用于实现Redis的操作。例如: ``` @Component public class RedisUtil { @Autowired private RedisTemplate<String, Object> redisTemplate; public void increment(String key) { redisTemplate.opsForValue().increment(key); } public Long get(String key) { return (Long) redisTemplate.opsForValue().get(key); } public void set(String key, Object value) { redisTemplate.opsForValue().set(key, value); } } ``` 在该类中,我们使用@Autowired注解注入了RedisTemplate实例,调用其相关方法实现对Redis的操作,例如增加点赞数、获取点赞数、设置点赞信息等。 4. 实现点赞功能实现点赞功能的Controller中,我们可以使用RedisUtil来操作Redis,例如: ``` @RestController public class LikeController { @Autowired private RedisUtil redisUtil; @GetMapping("/like/{id}") public String like(@PathVariable Long id) { String key = "article:like:" + id; redisUtil.increment(key); // 点赞数增加1 return "点赞成功"; } @GetMapping("/like/count/{id}") public Long count(@PathVariable Long id) { String key = "article:like:" + id; return redisUtil.get(key); // 获取点赞数 } } ``` 在这里,我们可以将Redis的键名定义为“article:like:{文章id}”,并使用increment方法实现点赞数的增加。需要注意的是,我们可以使用String类型来存储点赞数,但是如果需要保证点赞数的原子性操作,我们可以使用Redis中提供的incr命令。 这样,我们就实现点赞功能的简单实现。在实际生产中,我们可能还需要考虑点赞数的过期时间、防止重复点赞等问题,但是这里仅仅是提供了一个基础的实现思路。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值