微博点赞实战

代码地址:https://gitee.com/zhangmengxiang123/like
一、微博点赞业务场景分析

梳理点赞的业务场景,它由两个接口:
第一个:点赞或取消点赞,用户点击功能
第二个:查看帖子信息:通过用户id 和帖子id查看改帖子,查看该帖子点赞数,查看该用户是否点赞状态。

二、微博点赞的技术方案

点赞的关键技术就是要判断该用户是否点赞,已点赞的用户不允许重复点赞,即过滤重复,虽然业务不复杂,可以采用数据库
直接实现,但是对应微博这种高并发的场景,不可能查数据的,一般是缓存,即redis

第一个:点赞或取消点赞,用户点击功能
采用的是redis的set数据接口,key=like:postid value={userid}

采用sadd命令添加点赞

127.0.0.1: sadd like:1000 101
127.0.0.1: (int)1
127.0.0.1: sadd like:1000 102
127.0.0.1: (int)1
127.0.0.1: sadd like:1000 103
127.0.0.1: (int)1
127.0.0.1: smembers like:1000
127.0.0.1:  1)	101 2)	102 3)	103

采用srem命令,取消点赞

127.0.0.1: srem like:1000 101
127.0.0.1: (int)1
127.0.0.1: smembers like:1000
127.0.0.1: 
1)	102
2)	103

第二个:查看帖子信息:通过用户id 和帖子id查看改帖子,查看该帖子点赞数,查看该用户是否点赞状态。

采用scard命令,查看点赞总数

127.0.0.1: scard like:1000
127.0.0.1: (int)2

该用户是否点赞,采用sismember 判断某一个元素是否在set中

127.0.0.1: sismember like:1000 102
127.0.0.1: (int)1

三、案例实战:点赞代码实现

@Api(value = "点赞",tags = {"点赞接口实现"})
@RestController
@Slf4j
public class FabulousController {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 点赞
     */
    @ApiOperation(value = "点赞",notes = "点赞",httpMethod = "GET")
    @GetMapping(value = "/dolike",produces = "application/json;charset=utf-8")
    public String dolike(int postid, int userid) {
        String result = "";
        try {
            String key = "like:" + postid;
            Long object = this.redisTemplate.opsForSet().add(key, userid);
            if (object == 1) {
                result = "点赞成功";
            } else {
                result = "你已重复点赞!";
            }
            log.info("查询结果:{}", object);
        } catch (Exception e) {
            log.error("exception:", e.getMessage());
        }
        return result;
    }

    /**
     * 取消点赞
     */
    @ApiOperation(value = "取消点赞",notes = "取消点赞",httpMethod = "GET")
    @GetMapping(value = "/undolike",produces = "application/json;charset=utf-8")
    public String undolike(int postid, int userid) {
        String result = "";
        try {
            String key = "like:" + postid;
            Long object = this.redisTemplate.opsForSet().remove(key, userid);
            if (object == 1) {
                result = "取消成功";
            } else {
                result = "你已重复取消点赞!";
            }
            log.info("查询结果:{}", object);
        } catch (Exception e) {
            log.error("exception:", e.getMessage());
        }
        return result;
    }

    /**
     * 查看帖子信息
     * 根据id查询帖子信息,返回点赞总数和是否点赞
     */
    @ApiOperation(value = "查看帖子信息",notes = "查看帖子信息",httpMethod = "GET")
    @GetMapping(value = "/getpost")
    public Map getpost(int postid, int userid) {
        Map map = new HashMap<>();
        String result = "";
        try {
            String key = "like:" + postid;
            Long size = this.redisTemplate.opsForSet().size(key);
            Boolean bo = this.redisTemplate.opsForSet().isMember(key, userid);
            map.put("size", size);
            map.put("isLike", bo);
            log.info("查询结果:{}", bo);
        } catch (Exception e) {
            log.error("exception:", e.getMessage());
        }
        return map;
    }

    /**
     * 查询点赞明细,有那些人
     */
    @ApiOperation(value = "查询点赞明细",notes = "查询点赞明细",httpMethod = "GET")
    @GetMapping(value = "/likedetail")
    public Set likedetail(int postid) {
        Set set = null;
        try {
            String key = "like:" + postid;
            set = this.redisTemplate.opsForSet().members(key);
            log.info("查询结果:{}", set);
        } catch (Exception e) {
            log.error("exception:", e.getMessage());
        }
        return set;
    }
}

项目启动,通过swagger进行接口测试。
在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐