如何不复杂的设计与实现收藏功能?(Java版)

技术老男孩 2023-12-20 08:31 发表于广东

技术老男孩

分享技术路上的点滴,专注于后端技术,助力开发者成长,欢迎关注。

55篇原创内容

公众号

一、前言

最近业务有涉及收藏模块的设计与实现,需要在基础的功能上额外实现多一个收藏功能。

二、需求

需求场景:

  • 多个不同的业务。(这里就举掘金的例子,以下也是;例如:文章、小册、沸点等等)

  • 不同用户的收藏独立化。

  • 统计所有用户和当前用户的收藏情况。

  • 展示收藏分类对应详细内容的情况。(如:收藏文章/小册/沸点等的详细内容)

三、设计思路

经过了查询了部分资料,最终发现并决定用额外一张收藏表就能实现起来。

(一)数据库 mysql

这张表的字段就需要有业务id,业务类型,用户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 语句去实现。

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

  1. 当前用户的收藏对应业务;

  2. 各业务的收藏排行榜;

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

① 当前用户的收藏对应业务

-- 当前用户的收藏对应业务(当前查询 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);
}

总结

通过本篇学习,对枚举使用有一定明确,先分析业务需求,在查询的结果,进行枚举再细分处理;返回的结果再进行对其完善处理,最终完成业务需求。(即剩下的问题交给前端 ~ )

来源|juejin.cn/post/7279096030535090237

技术老男孩

分享技术路上的点滴,专注于后端技术,助力开发者成长,欢迎关注。

55篇原创内容

公众号

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
收藏夹和购物车系统的实现收藏夹子系统 (1) 【收藏指定图书】能收藏一本图书,并记录收藏日期(某年某月某日,如2016-12-12。所有日期都采用人工定义方式输入,不取机器日期)。图书的信息包括图书号(是唯一的)、书名、作者、出社、出日期、价格。 (2) 【查询指定图书】能按照图书号查询显示收藏夹中图书的相关信息(也可以扩展功能为按照书名、作者、出社、出日期、指定价格大小范围查询显示收藏夹中图书的相关信息)。 (3) 【按日期显示所有图书】能按照收藏日期的先后显示输出所收藏的所有图书的相关信息。 (4) 【移出收藏夹】可以把不想收藏的某一本指定图书号的图书直接移出收藏夹。 (5) 【加入购物车】将收藏夹中的某一本指定图书号的图书加入到购物车。 (6) 【按价格显示所有图书】能按照价格的大小显示输出收藏夹中的所有图书的相关信息。  购物车子系统 (1) 【直接加入购物车】把准备购买的一本图书直接加入购物车,同时记录加入购物车的日期。图书的信息包括图书号(是唯一的)、书名、作者、出社、出日期、价格、购买数量、购买金额(自动计算)。 (2) 【查询指定图书】能按照图书号查询显示购物车中准备购买的图书的相关信息(也可以扩展功能为按照书名、作者、出社、出日期、指定价格大小范围查询显示购物车中图书的相关信息)。 (3) 【修改购买数量】可以修改购物车中准备购买的某一本指定图书号的图书的数量,同时自动计算修改购买金额(购买金额=购买数量*价格)。 (4) 【删除指定图书并移到收藏夹】把购物车中的某一本指定图书号的图书删除并移到收藏夹。 (5) 【直接删除指定图书】可以把不想购买的某一本指定图书号的图书从购物车中删除。 (6) 【按图书号显示所有图书】把购物车中所有图书按照图书号列出每一本图书的图书号、书名、作者、出社、出日期、价格、购买数量、购买金额,最后列出总共有多少本图书、总金额是多少。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值