
Bug如山勤为径代码似海苦作舟。友友们好这里是苦瓜大王。今天学习的是黑马点评项目实战篇——达人探店部分的学习进行了一系列秒杀优化之后终于进入到相对轻松的章节啦今天我们将完成达人探店功能。笔记如下后续会一直更新黑马点评学习过程中的笔记、问题等请多多支持哦文章目录一、发布探店笔记二、查看探店笔记三、点赞功能1.业务思路2.具体实现(1)给Blog添加一个isLike字段(2)利用Redis的set集合修改点赞功能(3)修改两个查询Blog的业务判断赋值isLike字段四、点赞排行1.用sortedSet改造点赞(1)改造点赞业务(2)改造查询业务2.点赞排行的实现一、发布探店笔记表分析接口分析修改一下保存文件的位置改成自己的目录比如我的是D:\nginx-pro\nginx-hmdp-1.18.0\html\hmdp\imgs二、查看探店笔记接口分析给Blog类加上两个属性/** * 用户图标 */TableField(existfalse)//代表这个属性不属于数据库privateStringicon;/** * 用户姓名 */TableField(existfalse)privateStringname;BlogController代码------------------------------------BlogController---------------------------------------GetMapping(/hot)publicResultqueryHotBlog(RequestParam(valuecurrent,defaultValue1)Integercurrent){returnblogService.queryHotBlog(current);}GetMapping(/{id})publicResultqueryBlogById(PathVariable(id)Longid){returnblogService.queryBlogById(id);}BlogServiceImpl代码------------------------------------BlogServiceImpl--------------------------------------ResourceprivateIUserServiceuserService;/** * 查询博文详情 * param id * return */publicResultqueryBlogById(Longid){//1.查询blogBlogbloggetById(id);if(blognull)returnResult.fail(该Blog不存在);queryBlogUser(blog);returnResult.ok(blog);}/** * 查询热点博文 * param current * return **/OverridepublicResultqueryHotBlog(Integercurrent){// 根据用户查询PageBlogpagequery().orderByDesc(liked).page(newPage(current,SystemConstants.MAX_PAGE_SIZE));// 获取当前页数据ListBlogrecordspage.getRecords();// 查询用户records.forEach(this::queryBlogUser);returnResult.ok(records);}/** * 查询blog用户并封装属性进blog * param blog */privatevoidqueryBlogUser(Blogblog){LonguserIdblog.getUserId();UseruseruserService.getById(userId);blog.setName(user.getNickName());blog.setIcon(user.getIcon());}三、点赞功能1.业务思路2.具体实现(1)给Blog添加一个isLike字段/** * 是否点赞过了 */TableField(existfalse)privateBooleanisLike;(2)利用Redis的set集合修改点赞功能-------------------------------------BlogServiceImpl-------------------------------------ResourceprivateStringRedisTemplatestringRedisTemplate;/** * 点赞博文 * param id * return */publicResultlikeBlog(Longid){//1.获取登录用户LonguserIdUserHolder.getUser().getId();//2.判断当前登录用户是否已经点赞StringkeyBLOG_LIKED_KEYid;BooleanisMemberstringRedisTemplate.opsForSet().isMember(key,userId.toString());if(BooleanUtil.isFalse(isMember)){//3.未点赞// 3.1 数据库点单数1booleanisSuccessupdate().setSql(likedliked1).eq(id,id).update();// 3.2保存用户信息到redis集合中if(isSuccess){stringRedisTemplate.opsForSet().add(key,userId.toString());}}else{//4.点过赞//4.1 数据库点单数-1booleanisSuccessupdate().setSql(likedliked-1).eq(id,id).update();//4.2 从redis集合中移除用户信息if(isSuccess){stringRedisTemplate.opsForSet().remove(key,userId.toString());}}returnResult.ok();}(3)修改两个查询Blog的业务判断赋值isLike字段增加判断是否点赞过方法/** * 判断是否点赞过 */publicvoidisLikedBlog(Blogblog){//1.获取登录用户LonguserIdUserHolder.getUser().getId();//2.判断当前登录用户是否已经点赞StringkeyBLOG_LIKED_KEYblog.getId();BooleanisMemberstringRedisTemplate.opsForSet().isMember(key,userId.toString());blog.setIsLike(BooleanUtil.isTrue(isMember));}修改查询Blog的业务/** * 查询博文详情 * param id * return */publicResultqueryBlogById(Longid){//1.查询blogBlogbloggetById(id);if(blognull)returnResult.fail(该Blog不存在);queryBlogUser(blog);islIkeBlog(blog);returnResult.ok(blog);}/** * 查询热点博文 * param current * return */publicResultqueryHotBlog(Integercurrent){// 根据用户查询PageBlogpagequery().orderByDesc(liked).page(newPage(current,SystemConstants.MAX_PAGE_SIZE));// 获取当前页数据ListBlogrecordspage.getRecords();// 查询用户records.forEach(blog-{this.queryBlogUser(blog);this.islIkeBlog(blog);});returnResult.ok(records);}小贴士要记得修改拦截器配置把blog/hot拦截了不然线程不会保存请求的user四、点赞排行用查分数的形式查到就说明存在查不到就说明不存在1.用sortedSet改造点赞(1)改造点赞业务保存进sortSetstringRedisTemplate.opsForZSet().add(key,userId.toString(),System.currentTimeMillis());删除stringRedisTemplate.opsForZSet().remove(key,userId.toString());查是否存在DoublescorestringRedisTemplate.opsForZSet().score(key,userId.toString());if(scorenull){}优化后点赞功能整体代码/** * 点赞博文 * param id * return */publicResultlikeBlog(Longid){// 1.获取登录用户LonguserIdUserHolder.getUser().getId();// 2.判断当前登录用户是否已经点赞StringkeyBLOG_LIKED_KEYid;DoublescorestringRedisTemplate.opsForZSet().score(key,userId.toString());if(scorenull){//3.未点赞// 3.1 数据库点单数1booleanisSuccessupdate().setSql(likedliked1).eq(id,id).update();// 3.2保存用户信息到sortedSet集合中if(isSuccess){stringRedisTemplate.opsForZSet().add(key,userId.toString(),System.currentTimeMillis());}}else{//4.点过赞//4.1 数据库点单数-1booleanisSuccessupdate().setSql(likedliked-1).eq(id,id).update();//4.2 从redis集合中移除用户信息if(isSuccess){stringRedisTemplate.opsForZSet().remove(key,userId.toString());}}returnResult.ok();}(2)改造查询业务DoublescorestringRedisTemplate.opsForZSet().score(key,userId.toString());blog.setIsLike(score!null);判断是否点赞过代码/** * 判断是否点赞过 */publicvoidisLikedBlog(Blogblog){//1.获取登录用户LonguserIdUserHolder.getUser().getId();//2.判断当前登录用户是否已经点赞StringkeyBLOG_LIKED_KEYblog.getId();DoublescorestringRedisTemplate.opsForZSet().score(key,userId.toString());blog.setIsLike(score!null);}2.点赞排行的实现排行榜的顺序反了是因为数据库查询的时候用了IN需要手动指定顺序对查询继续进行改造-----------------------------------queryBlogLikes----------------------------------------ListLongidstop5.stream().map(Long::valueOf).collect(Collectors.toList());StringidStrStrUtil.join(,,ids);// 3.根据用户id查询用户 WHERE id IN ( 5 , 1 ) ORDER BY FIELD(id, 5, 1)ListUserDTO userDTOS userService.query().in(id,ids).last(ORDER BY FIELD(id,idStr)).list().stream().map(user-BeanUtil.copyProperties(user,UserDTO.class)).collect(Collectors.toList());这里还发现一个小bug用户在首页没有登陆的时候无需查看是否点过赞修改isLikedBlog代码/** * 判断是否点赞过 */publicvoidisLikedBlog(Blogblog){//1.获取登录用户UserDTOuserDTOUserHolder.getUser();if(userDTOnull)//用户未登录无需查询是否点过赞return;LonguserIduserDTO.getId();//2.判断当前登录用户是否已经点赞StringkeyBLOG_LIKED_KEYblog.getId();DoublescorestringRedisTemplate.opsForZSet().score(key,userId.toString());blog.setIsLike(score!null);}完整代码如下-----------------------------------BlogController----------------------------------------GetMapping(/likes/{id})publicResultqueryBlogLikes(PathVariable(id)Longid){returnblogService.queryBlogLikes(id);}----------------------------------BlogServiceImpl----------------------------------------/** * 查询博文点赞排行 * param id * return */publicResultqueryBlogLikes(Longid){StringkeyBLOG_LIKED_KEYid;// 1.查询top5的点赞用户 zrange key 0 4 SetString top5 stringRedisTemplate.opsForZSet().range(key, 0, 4);if(top5null||top5.isEmpty()){returnResult.ok(Collections.emptyList());}// 2.解析出其中的用户idListLongidstop5.stream().map(Long::valueOf).collect(Collectors.toList());StringidStrStrUtil.join(,,ids);// 3.根据用户id查询用户 WHERE id IN ( 5 , 1 ) ORDER BY FIELD(id, 5, 1) ListUserDTO userDTOS userService.query().in(id,ids).last(ORDER BY FIELD(id,idStr)).list().stream().map(user-BeanUtil.copyProperties(user,UserDTO.class)).collect(Collectors.toList());// 4.返回returnResult.ok(userDTOS);}以上就是黑马点评实战篇——达人探店部分的学习笔记仅供参考多多支持