个人收藏文章管理模块主要实现用户对感兴趣的文章进行收藏、取消收藏,以及查看自己的收藏列表等功能,是内容类应用中提升用户粘性的重要组成部分。下面我们将基于Spring Boot和MyBatis框架,一步步完成该模块的开发。

需求分析
首先明确模块需要实现的核心功能:
- 用户可以对文章进行收藏操作,同一篇文章同一用户只能收藏一次
- 用户可以对已收藏的文章进行取消收藏操作
- 用户可以分页查询自己的收藏文章列表,支持按收藏时间倒序排列
- 用户查看文章详情时,需要显示当前用户是否已收藏该文章
数据库设计
首先需要设计两张核心表,分别是文章表和收藏关系表,这里给出表结构示例:
文章表 article
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | bigint | 文章主键,自增 |
| title | varchar(200) | 文章标题 |
| content | text | 文章内容 |
| author_id | bigint | 文章作者ID |
| create_time | datetime | 文章创建时间 |
收藏关系表 user_article_favorite
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | bigint | 收藏记录主键,自增 |
| user_id | bigint | 用户ID |
| article_id | bigint | 文章ID |
| create_time | datetime | 收藏时间 |
| is_deleted | tinyint | 是否取消收藏,0未取消,1已取消 |
收藏关系表中设置user_id和article_id的唯一联合索引,避免同一用户重复收藏同一篇文章。
实体类开发
根据数据库表结构,创建对应的实体类:
Article实体类
public class Article {
private Long id;
private String title;
private String content;
private Long authorId;
private Date createTime;
// 省略getter、setter方法
}
UserArticleFavorite实体类
public class UserArticleFavorite {
private Long id;
private Long userId;
private Long articleId;
private Date createTime;
private Integer isDeleted;
// 省略getter、setter方法
}
持久层开发
使用MyBatis编写数据访问层的接口和映射文件,这里以收藏相关的核心方法为例:
UserArticleFavoriteMapper接口
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserArticleFavoriteMapper {
// 插入收藏记录
int insert(UserArticleFavorite favorite);
// 根据用户ID和文章ID查询收藏记录
UserArticleFavorite selectByUserIdAndArticleId(@Param("userId") Long userId, @Param("articleId") Long articleId);
// 更新收藏记录的删除状态(取消收藏)
int updateIsDeleted(@Param("id") Long id, @Param("isDeleted") Integer isDeleted);
// 分页查询用户的收藏文章列表
List<Article> selectFavoriteArticleList(@Param("userId") Long userId, @Param("offset") Integer offset, @Param("pageSize") Integer pageSize);
// 查询用户收藏文章总数
int selectFavoriteArticleCount(@Param("userId") Long userId);
}
对应的XML映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserArticleFavoriteMapper">
<insert id="insert" parameterType="com.example.entity.UserArticleFavorite">
INSERT INTO user_article_favorite (user_id, article_id, create_time, is_deleted)
VALUES (#{userId}, #{articleId}, #{createTime}, #{isDeleted})
</insert>
<select id="selectByUserIdAndArticleId" resultType="com.example.entity.UserArticleFavorite">
SELECT id, user_id, article_id, create_time, is_deleted
FROM user_article_favorite
WHERE user_id = #{userId} AND article_id = #{articleId}
</select>
<update id="updateIsDeleted">
UPDATE user_article_favorite
SET is_deleted = #{isDeleted}
WHERE id = #{id}
</update>
<select id="selectFavoriteArticleList" resultType="com.example.entity.Article">
SELECT a.id, a.title, a.content, a.author_id, a.create_time
FROM article a
INNER JOIN user_article_favorite f ON a.id = f.article_id
WHERE f.user_id = #{userId} AND f.is_deleted = 0
ORDER BY f.create_time DESC
LIMIT #{offset}, #{pageSize}
</select>
<select id="selectFavoriteArticleCount" resultType="int">
SELECT COUNT(1)
FROM user_article_favorite
WHERE user_id = #{userId} AND is_deleted = 0
</select>
</mapper>
业务层开发
在业务层封装核心逻辑,处理收藏、取消收藏、查询收藏列表等业务操作:
import com.example.entity.Article;
import com.example.entity.UserArticleFavorite;
import com.example.mapper.UserArticleFavoriteMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
@Service
public class FavoriteService {
@Resource
private UserArticleFavoriteMapper favoriteMapper;
// 收藏文章
@Transactional(rollbackFor = Exception.class)
public boolean favoriteArticle(Long userId, Long articleId) {
// 先查询是否已收藏
UserArticleFavorite existFavorite = favoriteMapper.selectByUserIdAndArticleId(userId, articleId);
if (existFavorite != null) {
// 如果之前取消过收藏,更新状态为未删除
if (existFavorite.getIsDeleted() == 1) {
favoriteMapper.updateIsDeleted(existFavorite.getId(), 0);
return true;
}
// 已经收藏过,直接返回
return false;
}
// 新增收藏记录
UserArticleFavorite favorite = new UserArticleFavorite();
favorite.setUserId(userId);
favorite.setArticleId(articleId);
favorite.setCreateTime(new Date());
favorite.setIsDeleted(0);
return favoriteMapper.insert(favorite) > 0;
}
// 取消收藏
@Transactional(rollbackFor = Exception.class)
public boolean cancelFavorite(Long userId, Long articleId) {
UserArticleFavorite existFavorite = favoriteMapper.selectByUserIdAndArticleId(userId, articleId);
if (existFavorite == null || existFavorite.getIsDeleted() == 1) {
return false;
}
return favoriteMapper.updateIsDeleted(existFavorite.getId(), 1) > 0;
}
// 分页查询收藏列表
public List<Article> getFavoriteList(Long userId, Integer pageNum, Integer pageSize) {
Integer offset = (pageNum - 1) * pageSize;
return favoriteMapper.selectFavoriteArticleList(userId, offset, pageSize);
}
// 查询收藏总数
public Integer getFavoriteCount(Long userId) {
return favoriteMapper.selectFavoriteArticleCount(userId);
}
// 判断用户是否收藏了某篇文章
public boolean isFavorite(Long userId, Long articleId) {
UserArticleFavorite existFavorite = favoriteMapper.selectByUserIdAndArticleId(userId, articleId);
return existFavorite != null && existFavorite.getIsDeleted() == 0;
}
}
控制层开发
最后编写接口控制层,对外提供HTTP接口:
import com.example.entity.Article;
import com.example.service.FavoriteService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/favorite")
public class FavoriteController {
@Resource
private FavoriteService favoriteService;
// 收藏文章接口
@PostMapping("/add")
public Map<String, Object> addFavorite(@RequestParam Long userId, @RequestParam Long articleId) {
Map<String, Object> result = new HashMap<>();
boolean success = favoriteService.favoriteArticle(userId, articleId);
result.put("success", success);
result.put("message", success ? "操作成功" : "操作失败");
return result;
}
// 取消收藏接口
@PostMapping("/cancel")
public Map<String, Object> cancelFavorite(@RequestParam Long userId, @RequestParam Long articleId) {
Map<String, Object> result = new HashMap<>();
boolean success = favoriteService.cancelFavorite(userId, articleId);
result.put("success", success);
result.put("message", success ? "操作成功" : "操作失败");
return result;
}
// 查询收藏列表接口
@GetMapping("/list")
public Map<String, Object> getFavoriteList(
@RequestParam Long userId,
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
Map<String, Object> result = new HashMap<>();
List<Article> list = favoriteService.getFavoriteList(userId, pageNum, pageSize);
Integer total = favoriteService.getFavoriteCount(userId);
result.put("list", list);
result.put("total", total);
result.put("pageNum", pageNum);
result.put("pageSize", pageSize);
return result;
}
// 判断用户是否收藏文章接口
@GetMapping("/check")
public Map<String, Object> checkFavorite(@RequestParam Long userId, @RequestParam Long articleId) {
Map<String, Object> result = new HashMap<>();
boolean isFavorite = favoriteService.isFavorite(userId, articleId);
result.put("isFavorite", isFavorite);
return result;
}
}
功能测试
完成开发后,我们可以通过Postman等工具测试接口功能:
- 调用收藏接口,传入用户ID和文章ID,检查数据库是否新增收藏记录
- 重复调用收藏接口,验证不会重复插入记录
- 调用取消收藏接口,检查收藏记录的is_deleted字段是否更新为1
- 调用查询收藏列表接口,验证返回的数据是否正确,分页是否正常
- 调用判断收藏状态接口,验证返回结果是否符合预期
以上就是一个完整的个人收藏文章管理模块的开发流程,开发者可以根据实际业务需求调整字段和逻辑,比如增加收藏分类、收藏备注等功能。
Java收藏管理模块Spring_BootMyBatisMySQL修改时间:2026-07-18 05:24:47