Web的点赞功能和收藏功能的设计思路

点赞功能的设计

实体类

package com.example.entity;
/*
点赞实体类
 */
public class Likes {
    private Integer id;
    /**
     * 关联id
     */
    private Integer fid;
    /**
     * 点赞人id
     */
    private Integer userId;
    /**
     * 模块
     */
    private String module;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getFid() {
        return fid;
    }

    public void setFid(Integer fid) {
        this.fid = fid;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getModule() {
        return module;
    }

    public void setModule(String module) {
        this.module = module;
    }
}

数据库设计

我们首先设计一个点赞表

CREATE TABLE `likes` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `fid` int(11) DEFAULT NULL COMMENT '关联ID',
  `user_id` int(11) DEFAULT NULL COMMENT '点赞人ID',
  `module` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '模块',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='点赞';

我解释一下,我为什么这么设计这个数据表

  1. fid: 这是一个外键,用于关联被点赞的对象。在不同的场景下,它可能代表不同的实体ID。例如,如果点赞的对象是博客文章,fid就存储博客文章的ID;如果是活动,就存储活动的ID。DEFAULT NULL表示这个字段可以为空,这在某些情况下可能是必要的,比如在实现“未明确点赞特定对象”的点赞时。

  2. user_id: 表示执行点赞操作的用户ID。这个字段用于记录是谁进行了点赞操作。它也是一个外键,关联到用户表。

  3. module: 这是一个字符串字段,用于指定点赞发生的模块或上下文。例如,它可以是’post’表示博客文章,'event’表示活动,或者其他任何您系统中可能的点赞对象类型。这增加了表的灵活性,使其不仅限于一种类型的实体。

整体流程

我先说一下整体流程:
用户发起点赞请求,Controller 接收请求并传递给 Service,Service 根据当前用户信息和点赞对象信息判断是点赞还是取消点赞,然后通过 Mapper 层操作数据库实现相应的功能。

业务逻辑处理

Controller
接收前端的HTTP请求,调用服务层的方法,并返回响应结果。

@RestController
@RequestMapping("/likes")
public class LikesController {

    @Resource
    LikesService likesService;

    // 点赞和取消
    @PostMapping("/set")
    public Result set(@RequestBody Likes likes) {
        likesService.set(likes);
        return Result.success();
    }

}

Service
点赞功能的业务逻辑。

@Service
public class LikesService {

    @Resource
    LikesMapper likesMapper;

    public void set(Likes likes) {
        Account currentUser = TokenUtils.getCurrentUser();
        likes.setUserId(currentUser.getId());
        Likes dblLikes = likesMapper.selectUserLikes(likes);
        if (dblLikes == null) {
            likesMapper.insert(likes);
        } else {
            likesMapper.deleteById(dblLikes.getId());
        }
    }

    /**
     * 查询当前用户是否点过赞
     */
    public Likes selectUserLikes(Integer fid, String module) {
        Account currentUser = TokenUtils.getCurrentUser();
        Likes likes = new Likes();
        likes.setUserId(currentUser.getId());
        likes.setFid(fid);
        likes.setModule(module);
        return likesMapper.selectUserLikes(likes);
    }

    public int selectByFidAndModule(Integer fid, String module) {
        return likesMapper.selectByFidAndModule(fid, module);
    }

}

  1. 获取当前用户
    首先,通过TokenUtils.getCurrentUser()方法获取当前登录的用户信息。这是通过解析用户的认证令牌(通常是JWT或其他形式的token)来实现的,确保了只有认证用户能进行点赞操作。

  2. 设置用户ID
    将当前用户的ID设置到Likes对象中。这是为了确保点赞信息与特定用户相关联,即知道是哪个用户进行了点赞或取消点赞操作。

  3. 查询已存在的点赞记录
    通过调用likesMapper.selectUserLikes(likes),查询数据库中是否已存在相同的点赞记录。这个查询基于传入的Likes对象,特别是依据用户ID、功能ID (fid) 和模块(module)。查询结果dblLikes将决定接下来的操作步骤。

  4. 处理点赞或取消点赞
    根据查询结果,业务逻辑分为两种情况:
    如果dblLikes为空:表示当前用户尚未对该fid和module点赞。因此,执行likesMapper.insert(likes),在数据库中插入一条新的点赞记录。这代表用户现在对该项目点赞。
    如果dblLikes不为空:表示已存在点赞记录,用户此次操作意在取消点赞。因此,执行likesMapper.deleteById(dblLikes.getId()),根据点赞记录的ID从数据库中删除这条记录。这代表用户取消了对该项目的点赞。

通过上述步骤,set方法有效地管理了点赞状态的切换,即从未点赞到点赞,或从已点赞到取消点赞。这种设计既简洁又高效,能够确保每个用户对每个fid和module的点赞状态唯一,且在用户决定改变心意时可以轻松地进行状态切换。

mapper

public interface LikesMapper {

    void insert(Likes likes);

    Likes selectUserLikes(Likes likes);

    void deleteById(Integer id);

    int selectByFidAndModule(@Param("fid") Integer fid, @Param("module") String module);
}

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.LikesMapper">


    <insert id="insert">
        insert into likes (fid, user_id, module) values (#{fid}, #{userId}, #{module})
    </insert>

    <delete id="deleteById">
        delete from likes where id = #{id}
    </delete>

    <select id="selectUserLikes" resultType="com.example.entity.Likes">
        select * from likes where fid = #{fid} and user_id = #{userId} and module = #{module}
    </select>

    <select id="selectByFidAndModule" resultType="java.lang.Integer">
        select count(*) from likes where fid = #{fid} and module = #{module}
    </select>

</mapper>

收藏功能的设计

收藏功能跟点赞功能一样的思路。

实体类

package com.example.entity;
/*
点赞实体类
 */
public class Collect {
    private Integer id;
    private Integer fid;
    private Integer userId;
    private String module;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getFid() {
        return fid;
    }

    public void setFid(Integer fid) {
        this.fid = fid;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getModule() {
        return module;
    }

    public void setModule(String module) {
        this.module = module;
    }
}

数据库设计

CREATE TABLE `collect` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `fid` int(11) DEFAULT NULL COMMENT '关联ID',
  `user_id` int(11) DEFAULT NULL COMMENT '点赞人ID',
  `module` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '模块',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='收藏';

整体流程

用户发起收藏请求,Controller 接收请求并传递给 Service,Service 根据当前用户信息和收藏对象信息判断是收藏还是取消收藏,然后通过 Mapper 层操作数据库实现相应的功能。

业务逻辑处理

controller

@RestController
@RequestMapping("/collect")
public class CollectController {

    @Resource
    CollectService collectService;

    // 收藏和取消
    @PostMapping("/set")
    public Result set(@RequestBody Collect collect) {
        collectService.set(collect);
        return Result.success();
    }

}

service

@Service
public class CollectService {

    @Resource
    CollectMapper collectMapper;

    public void set(Collect collect) {
        Account currentUser = TokenUtils.getCurrentUser();
        collect.setUserId(currentUser.getId());
        Collect dblCollect = collectMapper.selectUserCollect(collect);
        if (dblCollect == null) {
            collectMapper.insert(collect);
        } else {
            collectMapper.deleteById(dblCollect.getId());
        }
    }

    /**
     * 查询当前用户是否收藏过
     */
    public Collect selectUserCollect(Integer fid, String module) {
        Account currentUser = TokenUtils.getCurrentUser();
        Collect collect = new Collect();
        collect.setUserId(currentUser.getId());
        collect.setFid(fid);
        collect.setModule(module);
        return collectMapper.selectUserCollect(collect);
    }

    public int selectByFidAndModule(Integer fid, String module) {
        return collectMapper.selectByFidAndModule(fid, module);
    }

}

mapper

public interface CollectMapper {

    void insert(Collect collect);

    Collect selectUserCollect(Collect collect);

    void deleteById(Integer id);

    int selectByFidAndModule(@Param("fid") Integer fid, @Param("module") String module);
}

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.CollectMapper">


    <insert id="insert">
        insert into collect (fid, user_id, module) values (#{fid}, #{userId}, #{module})
    </insert>

    <delete id="deleteById">
        delete from collect where id = #{id}
    </delete>

    <select id="selectUserCollect" resultType="com.example.entity.Collect">
        select * from collect where fid = #{fid} and user_id = #{userId} and module = #{module}
    </select>

    <select id="selectByFidAndModule" resultType="java.lang.Integer">
        select count(*) from collect where fid = #{fid} and module = #{module}
    </select>

</mapper>
  • 25
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忘忧记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值