MySQL, Oracle, Linux, 软件架构及大数据技术知识分享平台

网站首页 > 精选文章 / 正文

Spring Boot中如何设计并一个点赞功能?

2024-12-17 13:22 huorong 精选文章 6 ℃ 0 评论

废话不多说直接上步骤,首先涉及到的就是需要操作的两个实体类对象一个是帖子实体、一个是用户点赞实体,这也是点赞功能的一个数据库模型。假设我们有一个Post(帖子)实体,包含了每个Post记录点赞数。然后Like实体来存储用户对每个帖子点赞的记录,以便避免用户重复点赞。如下所示。

实体类定义

Post实体

记录帖子内容和点赞数量。

@Entity
public class Post {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String content;
    private int likeCount;

    // getters and setters
}

Like实体

存储用户对某个帖子是否点赞。每条记录对应一个用户和一个帖子。

@Entity
public class Like {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "post_id", nullable = false)
    private Post post;

    @ManyToOne
    @JoinColumn(name = "user_id", nullable = false)
    private User user;

    // getters and setters
}

创建Repository

为Post和Like创建Repository,用于数据库操作,如下所示。

@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
}

@Repository
public interface LikeRepository extends JpaRepository<Like, Long> {
    Optional<Like> findByUserAndPost(User user, Post post);
    int countByPost(Post post);
}

其中,findByUserAndPost方法用于查找某个用户对某个帖子的点赞记录,以便判断是否已点赞。countByPost方法用于统计某个帖子的点赞数。

编写Service 层

接下就是在业务逻辑Service层中实现相关的点赞逻辑,例如判断是否已点赞、增加点赞记录等。

@Service
public class LikeService {
    @Autowired
    private PostRepository postRepository;

    @Autowired
    private LikeRepository likeRepository;

    public void likePost(Long postId, User user) {
        Post post = postRepository.findById(postId)
                .orElseThrow(() -> new RuntimeException("Post not found"));

        // 检查用户是否已对该帖子点赞
        if (likeRepository.findByUserAndPost(user, post).isPresent()) {
            throw new RuntimeException("You have already liked this post");
        }

        // 创建新的点赞记录
        Like like = new Like();
        like.setPost(post);
        like.setUser(user);
        likeRepository.save(like);

        // 更新帖子点赞数
        post.setLikeCount(likeRepository.countByPost(post));
        postRepository.save(post);
    }

    public void unlikePost(Long postId, User user) {
        Post post = postRepository.findById(postId)
                .orElseThrow(() -> new RuntimeException("Post not found"));

        Like like = likeRepository.findByUserAndPost(user, post)
                .orElseThrow(() -> new RuntimeException("You haven't liked this post"));

        // 删除点赞记录
        likeRepository.delete(like);

        // 更新帖子点赞数
        post.setLikeCount(likeRepository.countByPost(post));
        postRepository.save(post);
    }
}

介绍一下两个核心方法的作用,

  • likePost方法:其主要的作用就是用于点赞,在方法中首先检查用户是否已点赞,如果没有点赞,则添加一条新的点赞记录,并更新帖子的点赞数。
  • unlikePost方法:主要是用于取消点赞,在方法中首先检查用户是否已点赞,如果已经点赞,如果点赞了则删除记录,并更新帖子的点赞数。

编写Controller层

在Controller层中调用Service层的方法来实现用户点赞了取消点赞的功能。

@RestController
@RequestMapping("/posts")
public class PostController {
    @Autowired
    private LikeService likeService;

    @PostMapping("/{postId}/like")
    public ResponseEntity<String> likePost(@PathVariable Long postId, @AuthenticationPrincipal User user) {
        likeService.likePost(postId, user);
        return ResponseEntity.ok("Liked post successfully");
    }

    @PostMapping("/{postId}/unlike")
    public ResponseEntity<String> unlikePost(@PathVariable Long postId, @AuthenticationPrincipal User user) {
        likeService.unlikePost(postId, user);
        return ResponseEntity.ok("Unliked post successfully");
    }
}

获取帖子详情的时候,将点赞数量反馈到前端进行展示。

@GetMapping("/{postId}")
public ResponseEntity<Post> getPost(@PathVariable Long postId) {
    Post post = postRepository.findById(postId)
            .orElseThrow(() -> new RuntimeException("Post not found"));
    return ResponseEntity.ok(post);
}

处理并发问题

在高并发场景下,可能会出现多个用户重复点赞的功能,这种情况我们一般采用的方式是通过数据库唯一性约束分布式锁 来处理,如下所示。

使用数据库唯一性约束

在数据库中为Like表添加一个唯一约束,确保user_id和post_id的组合唯一,如果用户重复点赞,数据库会抛出唯一性约束异常。我们可以捕获这个异常并返回一个适当的提示信息。

使用分布式锁

在高并发场景中,一般可以通过Redis来实现分布式锁来防止并发安全问题。通过Redisson库实现对likePost方法的分布式锁控制,防止同一个用户多次点赞。

总结

通过上面的方式,我们就可以实现一个简单的点赞功能,在前端我们通过Ajax请求来分别发送点赞了取消点赞的请求。来及时的处理页面对于点赞数量的更新操作。我们也可以更具实际情况对相关的业务逻辑进行升级优化来保证系统的高效稳定。

Tags:manytoone

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言