【Java】简单的收藏功能如何实现?(附源码)

2023-12-19 21:26:15

前言

在最近的项目开发中,我们遇到了一个新的挑战:在已有的功能基础上增加一个全新的收藏模块。这个模块的设计和实现需要满足多元化的业务需求,并且在用户体验上做到个性化和独立化。
在这里插入图片描述

需求分析

我们的目标是创建一个适应多种业务场景的收藏功能。以掘金平台为例,我们需要考虑以下几个方面:

多元化的内容类型:不同种类的内容,如文章、小册、沸点等,都需要被纳入收藏功能的范畴。
1用户收藏的独立性:确保每位用户的收藏列表是独立且私密的,不会相互干扰。
2收藏统计:能够统计和展示所有用户以及当前用户的收藏情况。
3详细内容展示:不仅要显示收藏的分类(如文章、小册等),还要展示每个分类中具体收藏内容的详细信息。

设计方案

在深入研究和分析后,我们发现可以通过新增一张专门的收藏表来实现这一功能。

数据库设计(使用MySQL)

为了满足上述需求,我们设计的收藏表将包含以下关键字段:

1业务ID:用于标识被收藏内容的唯一ID。
2业务类型:表示被收藏内容的类型,如文章、小册、沸点等。
3用户ID:标识收藏该内容的用户。

结合这些字段,我们能够构建一个能够支撑多种业务场景的收藏模块,同时保证用户收藏的独立性和详细信息的展示。

通过精心设计和实现这一模块,我们可以提升用户体验,增强平台的互动性和个性化服务。
sql 生成表和数据脚本(模拟数据)如下:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for t_collect
-- ----------------------------
DROP TABLE IF EXISTS `t_collect`;
CREATE TABLE `t_collect`  (
  `id` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'id',
  `business_id` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '业务id',
  `user_id` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '用户id',
  `business_type` tinyint(4) NULL DEFAULT 0 COMMENT '业务类型 (1:文章;2:小册;3:沸点 )',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of t_collect
-- ----------------------------
INSERT INTO `t_collect` VALUES ('1', 'post_1', 'user_1', 1);
INSERT INTO `t_collect` VALUES ('2', 'post_2', 'user_1', 1);
INSERT INTO `t_collect` VALUES ('3', 'post_3', 'user_2', 1);
INSERT INTO `t_collect` VALUES ('4', 'post_3', 'user_1', 1);
INSERT INTO `t_collect` VALUES ('5', 'book_1', 'user_1', 2);
INSERT INTO `t_collect` VALUES ('6', 'book_2', 'user_3', 2);
INSERT INTO `t_collect` VALUES ('7', 'dot_1', 'user_2', 3);
INSERT INTO `t_collect` VALUES ('8', 'dot_2', 'user_2', 3);
INSERT INTO `t_collect` VALUES ('9', 'dot_2', 'user_3', 3);
INSERT INTO `t_collect` VALUES ('10', 'dot_3', 'user_3', 3);

SET FOREIGN_KEY_CHECKS = 1;
# 业务代码 mysql
有表也有数据,就先根据业务用 mysql 语句去实现。

根据需求场景来说,具体化之后的实现是需要有:

当前用户的收藏对应业务;
各业务的收藏排行榜;
当前用户对应的业务收藏详细内容的情况;
① 当前用户的收藏对应业务

```java
-- 当前用户的收藏对应业务(当前查询 user_id 为"user_1"SELECT business_type AS type, COUNT(1) AS count
FROM t_collect
WHERE user_id = 'user_1'
GROUP BY business_type;
-- 所有业务的收藏排行榜
SELECT user_id, business_type type, COUNT(1) count
FROM t_collect
GROUP BY user_id, business_type
ORDER BY business_type, count DESC;

-- 根据类型业务的收藏排行榜
SELECT business_type AS type, user_id, COUNT(1) AS count
FROM t_collect
WHERE business_type = 1
GROUP BY user_id;

结论:
在这里插入图片描述

当前用户对应的业务收藏详细内容的情况

这里是需要查询当前用户和对应业务类型匹配对应的收藏数据,再根据查询结果的业务 id 去查询对应业务表的数据即可查询详情内容。

-- 查询当前用户与业务类型对应的收藏记录(主要查出业务 id )
SELECT business_type AS type, user_id, business_id
FROM t_collect
WHERE business_type = 1
AND user_id = "user_1";

-- 再根据 business_type 和 business_id 在 java 代码业务类型枚举中查询对应业务表的数据
-- ...

业务代码 java
以下是基于 MyBatis-Plus 代码(且会以 jdk 8 lambda 表达式为主)

CollectTypeEnum.java

/**
 * @Author nanfnagzhe
 * @Description TODO 收藏对应业务类型的枚举类
 * @Date 2023/9/17
 **/
public enum CollectTypeEnum {
    /**
     * 业务类型 (1:文章;2:小册;3:沸点 )
     */

    POST(1, "文章"),
    BOOK(2, "小册"),
    DOT(3, "沸点"),
    ;
    private Integer code;
    private String text;

    CollectTypeEnum(Integer code, String text) {
        this.code = code;
        this.text = text;
    }

    public Integer getCode() {
        return code;
    }

    public String getText() {
        return text;
    }

    public Integer code() {
        return code;
    }

    /**
     * 根据 code 获取对应的内容(返回给前端)
     */
    public static String text(Integer code) {
        for (CollectTypeEnum one : CollectTypeEnum.values()) {
            if (one.code().equals(code)) {
                return one.getText();
            }
        }
        return null;
    }
}

代码因为和 sql 语句实现更加方便,查询出结果后,主要展示枚举类对应的使用。

CollectServiceImpl.java

/**
 * TODO: 当前用户的收藏对应业务
 *
 * @Author nanfangzhe
 * @Date 2023/9/17
 **/
@Override
public Map<String, Object> getListByType(Integer type) {
    Map<String, Object> resMap = new HashMap<>();
    QueryWrapper<CollectVo> wrapper = new QueryWrapper<>();
    wrapper.eq("user_id", "user_1");
    wrapper.eq("business_type", type);
    wrapper.groupBy("business_type");
    List<CollectVo> list = collectMapper.selectList(wrapper);
    list.forEach(one -> {
        one.setBusinessName(CollectTypeEnum.text(one.getBusinessType()));
    });
    resMap.put("data", list);
    return resMap;
}

// ...
// 其他代码实现类似,主要围绕枚举展示方便使用,反馈给前端数据。

/**
  * TODO: 当前用户的收藏对应业务
  *
  * @Author nanfangzhe
  * @Date 2023/9/17
  **/
@Override
public Map<String, Object> getDetailsListByType(Integer type) {
    Map<String, Object> resMap = new HashMap<>();
    QueryWrapper<CollectVo> wrapper = new QueryWrapper<>();
    wrapper.eq("user_id", "user_1");
    wrapper.eq("business_type", type);
    wrapper.groupBy("business_type");
    List<CollectVo> list = collectMapper.selectList(wrapper);
    // 获取对应业务 id List
    List<String> businessIdList = list.stream().map(CollectVo::getBusinessId).collect(Collectors.toList());
    Object data = new Object();
    if(type.equals(CollectTypeEnum.POST.code())){
        // 文章业务处理
        data = getPostList(businessIdList);
    } else if (type.equals(CollectTypeEnum.DOT.code())) {
        // 文章业务处理
        data = getDotList(businessIdList);
    }else if (type.equals(CollectTypeEnum.DOT.code())) {
        // 文章业务处理
        data = getBookList(businessIdList);
    }
    return resMap;
}

private Object getPostList(List<String> businessIdList){
    // 文章业务对应的处理
    return postService.selectBatchIds(businessIdList);
}
private Object getBookList(List<String> businessIdList){
    // 小册业务对应的处理
    return bookService.selectBatchIds(businessIdList);
}
private Object getDotList(List<String> businessIdList){
    // 沸点业务对应的处理
    return dotService.selectBatchIds(businessIdList);

学习总结

本次学习之旅使我对枚举(Enumeration)的应用有了更深的理解。我们首先从深入分析业务需求入手,然后通过精确查询,对问题进行枚举分类和细化处理。针对每种枚举类型,我们设计了相应的解决方案,确保了结果的准确性和高效性。在此过程中,我们对返回结果进行了细致的优化和完善,确保最终能够满足业务需求。这次的学习经历不仅提升了我的问题分析和解决能力,也加深了我对枚举在复杂问题处理中的价值认识。最终,我们将剩余的工作交由前端团队完成,以确保整个项目的流畅协作和高效完成。

文章来源:https://blog.csdn.net/liaozp88/article/details/135080106
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。