12.2_黑马Redis实战篇达人探店&好友关注

目录

实战篇03

thinking :提取公共部分为一个方法的快捷键?

thinking:redis中的ismember?

thinking:BooleanUtil.isTrue?

实战篇04

thinking:zscore的用法?

thinking:stream().map().collect?

thinking:引用静态方法?JAVA中的双冒号? 

thinking:StringUtils.join的用法?

thinking:StrUtil.join()?

实战篇05

实战篇06

thinking:在redis中求交集?  用inersect。

实战篇07

实战篇08

thinking:System.currentTimeMillis()?

​编辑 thinking:时间戳?​编辑

实战篇09

实战篇10

​编辑 thinking:JAVA中的long和int有什么区别?

thinking:为什么long类型的变量需要加上L?float类型的变量要加上F?


实战篇03

thinking :提取公共部分为一个方法的快捷键?

ctrl + alt + m

thinking:redis中的ismember?

redis五大集合之一(Set集合常用命令)_redis set ismember-CSDN博客

12.2_黑马Redis实战篇达人探店&好友关注_第1张图片

12.2_黑马Redis实战篇达人探店&好友关注_第2张图片

可以简化为:

thinking:BooleanUtil.isTrue?

hutool工具包快速入门_beanutil.fillbeanwithmap-CSDN博客

12.2_黑马Redis实战篇达人探店&好友关注_第3张图片

package com.hmdp.service.impl;

import cn.hutool.core.util.BooleanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hmdp.dto.Result;
import com.hmdp.entity.Blog;
import com.hmdp.entity.User;
import com.hmdp.mapper.BlogMapper;
import com.hmdp.service.IBlogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmdp.service.IUserService;
import com.hmdp.utils.SystemConstants;
import com.hmdp.utils.UserHolder;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * 

* 服务实现类 *

* * @author 虎哥 * @since 2021-12-22 */ @Service public class BlogServiceImpl extends ServiceImpl implements IBlogService { @Resource private IUserService userService; @Resource private StringRedisTemplate stringRedisTemplate; @Override public Result queryHotBlog(Integer current) { // 根据用户查询 Page page = query() .orderByDesc("liked") .page(new Page<>(current, SystemConstants.MAX_PAGE_SIZE)); // 获取当前页数据 List records = page.getRecords(); // 查询用户 records.forEach(blog -> { this.queryBlogUser(blog); this.isBlockLiked(blog); }); return Result.ok(records); } @Override public Result queryBlogById(Long id) { //1. 查询blog Blog blog =getById(id); if(blog == null){ return Result.fail("笔记不存在!"); } //2. 查询blog有关的用户 queryBlogUser(blog); //3.查询blog是否被点赞 isBlockLiked(blog); return Result.ok(blog); } private void isBlockLiked(Blog blog) { //1.判断当前登录用户 Long userId = UserHolder.getUser().getId(); //2.判断当前登录用户是否已经点赞 String key ="blog:liked:"+blog.getId(); Boolean isMember = stringRedisTemplate.opsForSet().isMember(key, userId.toString()); blog.setIsLike(BooleanUtil.isTrue(isMember)); } @Override public Result likeBlog(Long id) { //1.判断当前登录用户 Long userId = UserHolder.getUser().getId(); //2.判断当前登录用户是否已经点赞 String key ="blog:liked:"+id; Boolean isMember = stringRedisTemplate.opsForSet().isMember(key, userId.toString()); if(BooleanUtil.isFalse(isMember)) { //3.如果未点赞,可以点赞 //3.1数据库点赞数 +1 boolean isSuccess = update().setSql("liked = liked + 1").eq("id", id).update(); //3.2保存用户到Redis的set集合 if (isSuccess) { stringRedisTemplate.opsForSet().add(key, userId.toString()); } }else { //4如果已点赞,取消点赞 //4.1数据库点赞数 -1 boolean isSuccess = update().setSql("liked = liked + 1").eq("id", id).update(); //4.2把用户从Redis的set集合移除 if (isSuccess) { stringRedisTemplate.opsForSet().remove(key, userId.toString()); } } return Result.ok(); } private void queryBlogUser(Blog blog) { Long userId = blog.getUserId(); User user = userService.getById(userId); blog.setName(user.getNickName()); blog.setIcon(user.getIcon()); } }

12.2_黑马Redis实战篇达人探店&好友关注_第4张图片

实战篇04

12.2_黑马Redis实战篇达人探店&好友关注_第5张图片

thinking:zscore的用法?

Redis zrangebylex的使用 | Redis sorted_set不可不知的秘密_血煞长虹的博客-CSDN博客

12.2_黑马Redis实战篇达人探店&好友关注_第6张图片

12.2_黑马Redis实战篇达人探店&好友关注_第7张图片

thinking:stream().map().collect?

12.2_黑马Redis实战篇达人探店&好友关注_第8张图片

thinking:引用静态方法?JAVA中的双冒号? 

当时看黑马上下部的时候一直没有搞懂的内容之一。现在来恶补一下。

方法引用-02-引用静态方法_哔哩哔哩_bilibili

12.2_黑马Redis实战篇达人探店&好友关注_第9张图片

12.2_黑马Redis实战篇达人探店&好友关注_第10张图片

 12.2_黑马Redis实战篇达人探店&好友关注_第11张图片

 12.2_黑马Redis实战篇达人探店&好友关注_第12张图片12.2_黑马Redis实战篇达人探店&好友关注_第13张图片

 12.2_黑马Redis实战篇达人探店&好友关注_第14张图片

接着判断它是否符合以下三个要求

12.2_黑马Redis实战篇达人探店&好友关注_第15张图片12.2_黑马Redis实战篇达人探店&好友关注_第16张图片

接着,我们来看看视频中的例子

Java中Long::valueOf是什么意思_long.valueof-CSDN博客

 有几篇讲JAVA双冒号的文章也挺好的,可以看看。

深入理解Java双冒号(::)运算符的使用(*)_java 双冒号_Firm陈的博客-CSDN博客

12.2_黑马Redis实战篇达人探店&好友关注_第17张图片

Java 中的双冒号“::”_java ::_JFS_Study的博客-CSDN博客  

 发现很多知识点当时很难理解,一段时间之后就突然开窍。

遂决定明年暑假前把JAVA基础篇再二刷一遍。

thinking:StringUtils.join的用法?

StringUtils.join的用法_stringutils.join用法-CSDN博客

12.2_黑马Redis实战篇达人探店&好友关注_第18张图片

thinking:StrUtil.join()?

Hutool Java开发工具包_strutil.join-CSDN博客

12.2_黑马Redis实战篇达人探店&好友关注_第19张图片

 Hutool,轻松玩转字符串操作, 都是案例,值得收藏!_hutool 字符串拼接-CSDN博客

12.2_黑马Redis实战篇达人探店&好友关注_第20张图片

package com.hmdp.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hmdp.dto.Result;
import com.hmdp.dto.UserDTO;
import com.hmdp.entity.Blog;
import com.hmdp.entity.User;
import com.hmdp.mapper.BlogMapper;
import com.hmdp.service.IBlogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmdp.service.IUserService;
import com.hmdp.utils.SystemConstants;
import com.hmdp.utils.UserHolder;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.hmdp.utils.RedisConstants.BLOG_LIKED_KEY;

/**
 * 

* 服务实现类 *

* * @author 虎哥 * @since 2021-12-22 */ @Service public class BlogServiceImpl extends ServiceImpl implements IBlogService { @Resource private IUserService userService; @Resource private StringRedisTemplate stringRedisTemplate; @Override public Result queryHotBlog(Integer current) { // 根据用户查询 Page page = query() .orderByDesc("liked") .page(new Page<>(current, SystemConstants.MAX_PAGE_SIZE)); // 获取当前页数据 List records = page.getRecords(); // 查询用户 records.forEach(blog -> { this.queryBlogUser(blog); this.isBlockLiked(blog); }); return Result.ok(records); } @Override public Result queryBlogById(Long id) { //1. 查询blog Blog blog =getById(id); if(blog == null){ return Result.fail("笔记不存在!"); } //2. 查询blog有关的用户 queryBlogUser(blog); //3.查询blog是否被点赞 isBlockLiked(blog); return Result.ok(blog); } private void isBlockLiked(Blog blog) { //1.获取登录用户 UserDTO user = UserHolder.getUser(); if(user == null){ //用户未登录,无需查询是否点赞 return; } //1.判断当前登录用户 Long userId = UserHolder.getUser().getId(); //2.判断当前登录用户是否已经点赞 String key ="blog:liked:"+blog.getId(); Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString()); blog.setIsLike(score != null); } @Override public Result likeBlog(Long id) { //1.判断当前登录用户 Long userId = UserHolder.getUser().getId(); //2.判断当前登录用户是否已经点赞 String key =BLOG_LIKED_KEY+id; Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString()); if(score == null) { //3.如果未点赞,可以点赞 //3.1数据库点赞数 +1 boolean isSuccess = update().setSql("liked = liked + 1").eq("id", id).update(); //3.2保存用户到Redis的set集合 if (isSuccess) { stringRedisTemplate.opsForZSet().add(key, userId.toString(),System.currentTimeMillis()); } }else { //4如果已点赞,取消点赞 //4.1数据库点赞数 -1 boolean isSuccess = update().setSql("liked = liked + 1").eq("id", id).update(); //4.2把用户从Redis的set集合移除 if (isSuccess) { stringRedisTemplate.opsForZSet().remove(key, userId.toString()); } } return Result.ok(); } @Override public Result queryBlogLikes(Long id) { String key =BLOG_LIKED_KEY + id; //1.查询top5的点赞用户 zrange key 0 4 Set top5 = stringRedisTemplate.opsForZSet().range(key, 0, 4); if(top5 ==null || top5.isEmpty()){ return Result.ok(Collections.emptyList()); } //2.解析出其中的用户id List ids = top5.stream().map(Long::valueOf).collect(Collectors.toList()); String idStr = StrUtil.join(",", ids); //3.根据用户id查询用户 List 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.返回 return Result.ok(userDTOS); } private void queryBlogUser(Blog blog) { Long userId = blog.getUserId(); User user = userService.getById(userId); blog.setName(user.getNickName()); blog.setIcon(user.getIcon()); } }

实战篇05

package com.hmdp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hmdp.dto.Result;
import com.hmdp.entity.Follow;
import com.hmdp.mapper.FollowMapper;
import com.hmdp.service.IFollowService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmdp.utils.UserHolder;
import org.springframework.stereotype.Service;

/**
 * 

* 服务实现类 *

* * @author 虎哥 * @since 2021-12-22 */ @Service public class FollowServiceImpl extends ServiceImpl implements IFollowService { @Override public Result follow(Long followUserId, Boolean isFollow) { //1.获取登录用户 Long userId = UserHolder.getUser().getId(); //1.判断到底是关注还是取关 if(isFollow){ //2.关注,新增数据 Follow follow = new Follow(); follow.setUserId(userId); follow.setFollowUserId(followUserId); save(follow); } else{ //3.取关,删除 remove(new QueryWrapper() .eq("user_id",userId) .eq("follow_user_id",followUserId)); } return Result.ok(); } @Override public Result isFollow(Long followUserId) { //1.获取登录用户 Long userId = UserHolder.getUser().getId(); //2.查询是否关注 Integer count = query().eq("user_id", userId) .eq("follow_user_id", followUserId).count(); return Result.ok(count > 0 ); } }

实战篇06

thinking:在redis中求交集?  用inersect。

12.2_黑马Redis实战篇达人探店&好友关注_第21张图片

package com.hmdp.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hmdp.dto.Result;
import com.hmdp.dto.UserDTO;
import com.hmdp.entity.Follow;
import com.hmdp.mapper.FollowMapper;
import com.hmdp.service.IFollowService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmdp.service.IUserService;
import com.hmdp.utils.CacheClient;
import com.hmdp.utils.UserHolder;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 

* 服务实现类 *

* * @author 虎哥 * @since 2021-12-22 */ @Service public class FollowServiceImpl extends ServiceImpl implements IFollowService { @Resource private StringRedisTemplate stringRedisTemplate; @Resource private IUserService userService; @Override public Result follow(Long followUserId, Boolean isFollow) { //1.获取登录用户 Long userId = UserHolder.getUser().getId(); String key ="follows:" + userId; //1.判断到底是关注还是取关 if(isFollow){ //2.关注,新增数据 Follow follow = new Follow(); follow.setUserId(userId); follow.setFollowUserId(followUserId); boolean isSuccess = save(follow); if(isSuccess){ //把关注用户的id,放入redis的set集合 stringRedisTemplate.opsForSet().add(key,followUserId.toString()); } } else{ //3.取关,删除 boolean isSuccess = remove(new QueryWrapper() .eq("user_id", userId) .eq("follow_user_id", followUserId)); if (isSuccess) { //把关注用户的id从Redis集合中移除 stringRedisTemplate.opsForSet().remove(key, followUserId.toString()); } } return Result.ok(); } @Override public Result isFollow(Long followUserId) { //1.获取登录用户 Long userId = UserHolder.getUser().getId(); //2.查询是否关注 Integer count = query().eq("user_id", userId) .eq("follow_user_id", followUserId).count(); return Result.ok(count > 0 ); } @Override public Result followCommons(Long id) { //1.获取当前用户 Long userId = UserHolder.getUser().getId(); String key = "follows:"+userId; //2.求交集 String key2 = "follows"+ id; Set intersect = stringRedisTemplate.opsForSet().intersect(key, key2); if(intersect == null || intersect.isEmpty()){ //无交集 return Result.ok(Collections.emptyList()); } //3.解析id集合 List ids = intersect.stream().map(Long::valueOf).collect(Collectors.toList()); //4.查询用户 List users = userService.listByIds(ids) .stream() .map(user -> BeanUtil.copyProperties(user, UserDTO.class)) .collect(Collectors.toList()); return Result.ok(users); } }

实战篇07

12.2_黑马Redis实战篇达人探店&好友关注_第22张图片

12.2_黑马Redis实战篇达人探店&好友关注_第23张图片

12.2_黑马Redis实战篇达人探店&好友关注_第24张图片

12.2_黑马Redis实战篇达人探店&好友关注_第25张图片

12.2_黑马Redis实战篇达人探店&好友关注_第26张图片12.2_黑马Redis实战篇达人探店&好友关注_第27张图片

实战篇08

对于数据经常发生变化的,用sortset处理分页问题 

12.2_黑马Redis实战篇达人探店&好友关注_第28张图片

thinking:System.currentTimeMillis()?

System.currentTimeMillis()用法及其计算方式与时间的单位转换_Tan.]der的博客-CSDN博客

12.2_黑马Redis实战篇达人探店&好友关注_第29张图片

Java获取当前系统时间-CSDN博客

12.2_黑马Redis实战篇达人探店&好友关注_第30张图片

12.2_黑马Redis实战篇达人探店&好友关注_第31张图片 thinking:时间戳?

 获取系统时间以及时间戳的理解与使用_系统时间戳-CSDN博客

package com.hmdp.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hmdp.dto.Result;
import com.hmdp.dto.UserDTO;
import com.hmdp.entity.Blog;
import com.hmdp.entity.Follow;
import com.hmdp.entity.User;
import com.hmdp.mapper.BlogMapper;
import com.hmdp.service.IBlogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmdp.service.IFollowService;
import com.hmdp.service.IUserService;
import com.hmdp.utils.SystemConstants;
import com.hmdp.utils.UserHolder;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.hmdp.utils.RedisConstants.BLOG_LIKED_KEY;

/**
 * 

* 服务实现类 *

* * @author 虎哥 * @since 2021-12-22 */ @Service public class BlogServiceImpl extends ServiceImpl implements IBlogService { @Resource private IUserService userService; @Resource private StringRedisTemplate stringRedisTemplate; @Resource private IFollowService followService; @Override public Result queryHotBlog(Integer current) { // 根据用户查询 Page page = query() .orderByDesc("liked") .page(new Page<>(current, SystemConstants.MAX_PAGE_SIZE)); // 获取当前页数据 List records = page.getRecords(); // 查询用户 records.forEach(blog -> { this.queryBlogUser(blog); this.isBlockLiked(blog); }); return Result.ok(records); } @Override public Result queryBlogById(Long id) { //1. 查询blog Blog blog =getById(id); if(blog == null){ return Result.fail("笔记不存在!"); } //2. 查询blog有关的用户 queryBlogUser(blog); //3.查询blog是否被点赞 isBlockLiked(blog); return Result.ok(blog); } private void isBlockLiked(Blog blog) { //1.获取登录用户 UserDTO user = UserHolder.getUser(); if(user == null){ //用户未登录,无需查询是否点赞 return; } //1.判断当前登录用户 Long userId = UserHolder.getUser().getId(); //2.判断当前登录用户是否已经点赞 String key ="blog:liked:"+blog.getId(); Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString()); blog.setIsLike(score != null); } @Override public Result likeBlog(Long id) { //1.判断当前登录用户 Long userId = UserHolder.getUser().getId(); //2.判断当前登录用户是否已经点赞 String key =BLOG_LIKED_KEY+id; Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString()); if(score == null) { //3.如果未点赞,可以点赞 //3.1数据库点赞数 +1 boolean isSuccess = update().setSql("liked = liked + 1").eq("id", id).update(); //3.2保存用户到Redis的set集合 if (isSuccess) { stringRedisTemplate.opsForZSet().add(key, userId.toString(),System.currentTimeMillis()); } }else { //4如果已点赞,取消点赞 //4.1数据库点赞数 -1 boolean isSuccess = update().setSql("liked = liked + 1").eq("id", id).update(); //4.2把用户从Redis的set集合移除 if (isSuccess) { stringRedisTemplate.opsForZSet().remove(key, userId.toString()); } } return Result.ok(); } @Override public Result queryBlogLikes(Long id) { String key =BLOG_LIKED_KEY + id; //1.查询top5的点赞用户 zrange key 0 4 Set top5 = stringRedisTemplate.opsForZSet().range(key, 0, 4); if(top5 ==null || top5.isEmpty()){ return Result.ok(Collections.emptyList()); } //2.解析出其中的用户id List ids = top5.stream().map(Long::valueOf).collect(Collectors.toList()); String idStr = StrUtil.join(",", ids); //3.根据用户id查询用户 List 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.返回 return Result.ok(userDTOS); } @Override public Result saveBlog(Blog blog) { //1 获取登录用户 UserDTO user = UserHolder.getUser(); blog.setUserId(user.getId()); //2 保存探店笔记 boolean isSuccess = save(blog); if (!isSuccess){ return Result.fail("新增笔记失败!"); } //3 查询笔记作者的所有粉丝 List follows = followService.query().eq("follow_user_id", user.getId()).list(); //4 推送笔记id给所有粉丝 for(Follow follow : follows){ //4.1 获取粉丝id Long userId = follow.getUserId(); //4.2推送 String key = "feed:" + userId; stringRedisTemplate.opsForZSet().add(key,blog.getId().toString(),System.currentTimeMillis()); } //5 返回id return Result.ok(blog.getId()); } private void queryBlogUser(Blog blog) { Long userId = blog.getUserId(); User user = userService.getById(userId); blog.setName(user.getNickName()); blog.setIcon(user.getIcon()); } }

实战篇09

12.2_黑马Redis实战篇达人探店&好友关注_第32张图片

实战篇10

12.2_黑马Redis实战篇达人探店&好友关注_第33张图片

12.2_黑马Redis实战篇达人探店&好友关注_第34张图片 thinking:JAVA中的long和int有什么区别?

12.2_黑马Redis实战篇达人探店&好友关注_第35张图片

 java long 区别_java中long和int的区别-CSDN博客

thinking:为什么long类型的变量需要加上L?float类型的变量要加上F?

运算符-04-05-隐式转换和强制转换_哔哩哔哩_bilibili

12.2_黑马Redis实战篇达人探店&好友关注_第36张图片

意思就是说:30本身是int类型,可是你现在想要它变成long类型。

而JAVA中的隐形转化,会自动将int类型转化未long类型。

因此,JAVA把你想做的事情帮你做了。因此,long num1 = 30 才可以成立

而1111111111111111111超过了int的取值范围,就已经出bug了。无法再帮你转long类型了

12.2_黑马Redis实战篇达人探店&好友关注_第37张图片

而double的取值范围最大,就无法自动转化了。得自己手动转化才可以。 

为什么定义long类型跟float类型的变量时要加L和F_java中long类型为什么要加l_Cristo_Li的博客-CSDN博客

12.2_黑马Redis实战篇达人探店&好友关注_第38张图片

【Java】double|float 区别_java float和double-CSDN博客

 

listByIds 无法保证在数据库中按照一定的顺序进行查找,因此要用自定义sql语句才可以完成这个操作。

package com.hmdp.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hmdp.dto.Result;
import com.hmdp.dto.ScrollResult;
import com.hmdp.dto.UserDTO;
import com.hmdp.entity.Blog;
import com.hmdp.entity.Follow;
import com.hmdp.entity.User;
import com.hmdp.mapper.BlogMapper;
import com.hmdp.service.IBlogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmdp.service.IFollowService;
import com.hmdp.service.IUserService;
import com.hmdp.utils.SystemConstants;
import com.hmdp.utils.UserHolder;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.hmdp.utils.RedisConstants.BLOG_LIKED_KEY;
import static com.hmdp.utils.RedisConstants.FEED_KEY;

/**
 * 

* 服务实现类 *

* * @author 虎哥 * @since 2021-12-22 */ @Service public class BlogServiceImpl extends ServiceImpl implements IBlogService { @Resource private IUserService userService; @Resource private StringRedisTemplate stringRedisTemplate; @Resource private IFollowService followService; @Override public Result queryHotBlog(Integer current) { // 根据用户查询 Page page = query() .orderByDesc("liked") .page(new Page<>(current, SystemConstants.MAX_PAGE_SIZE)); // 获取当前页数据 List records = page.getRecords(); // 查询用户 records.forEach(blog -> { this.queryBlogUser(blog); this.isBlockLiked(blog); }); return Result.ok(records); } @Override public Result queryBlogById(Long id) { //1. 查询blog Blog blog =getById(id); if(blog == null){ return Result.fail("笔记不存在!"); } //2. 查询blog有关的用户 queryBlogUser(blog); //3.查询blog是否被点赞 isBlockLiked(blog); return Result.ok(blog); } private void isBlockLiked(Blog blog) { //1.获取登录用户 UserDTO user = UserHolder.getUser(); if(user == null){ //用户未登录,无需查询是否点赞 return; } //1.判断当前登录用户 Long userId = UserHolder.getUser().getId(); //2.判断当前登录用户是否已经点赞 String key ="blog:liked:"+blog.getId(); Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString()); blog.setIsLike(score != null); } @Override public Result likeBlog(Long id) { //1.判断当前登录用户 Long userId = UserHolder.getUser().getId(); //2.判断当前登录用户是否已经点赞 String key =BLOG_LIKED_KEY+id; Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString()); if(score == null) { //3.如果未点赞,可以点赞 //3.1数据库点赞数 +1 boolean isSuccess = update().setSql("liked = liked + 1").eq("id", id).update(); //3.2保存用户到Redis的set集合 if (isSuccess) { stringRedisTemplate.opsForZSet().add(key, userId.toString(),System.currentTimeMillis()); } }else { //4如果已点赞,取消点赞 //4.1数据库点赞数 -1 boolean isSuccess = update().setSql("liked = liked + 1").eq("id", id).update(); //4.2把用户从Redis的set集合移除 if (isSuccess) { stringRedisTemplate.opsForZSet().remove(key, userId.toString()); } } return Result.ok(); } @Override public Result queryBlogLikes(Long id) { String key =BLOG_LIKED_KEY + id; //1.查询top5的点赞用户 zrange key 0 4 Set top5 = stringRedisTemplate.opsForZSet().range(key, 0, 4); if(top5 ==null || top5.isEmpty()){ return Result.ok(Collections.emptyList()); } //2.解析出其中的用户id List ids = top5.stream().map(Long::valueOf).collect(Collectors.toList()); String idStr = StrUtil.join(",", ids); //3.根据用户id查询用户 List 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.返回 return Result.ok(userDTOS); } @Override public Result saveBlog(Blog blog) { //1 获取登录用户 UserDTO user = UserHolder.getUser(); blog.setUserId(user.getId()); //2 保存探店笔记 boolean isSuccess = save(blog); if (!isSuccess){ return Result.fail("新增笔记失败!"); } //3 查询笔记作者的所有粉丝 List follows = followService.query().eq("follow_user_id", user.getId()).list(); //4 推送笔记id给所有粉丝 for(Follow follow : follows){ //4.1 获取粉丝id Long userId = follow.getUserId(); //4.2推送 String key = "feed:" + userId; stringRedisTemplate.opsForZSet().add(key,blog.getId().toString(),System.currentTimeMillis()); } //5 返回id return Result.ok(blog.getId()); } @Override public Result queryBlogOfFollow(Long max, Integer offset) { //1.获取当前用户 Long userId = UserHolder.getUser().getId(); //2.查询收件箱 String key = FEED_KEY + userId; Set> typedTuples = stringRedisTemplate .opsForZSet() .reverseRangeByScoreWithScores(key, 0, max, offset, 2); //3.非空判断 if(typedTuples == null || typedTuples.isEmpty()){ return Result.ok(); } //4.解析数据 :blogId minTime(时间戳) offset List ids =new ArrayList<>(typedTuples.size()); long minTime =0; int os = 1; for(ZSetOperations.TypedTuple tuple : typedTuples){ //4.1 获取id ids.add(Long.valueOf(tuple.getValue())); //4.2 获取分数(时间戳) long time = tuple.getScore().longValue(); if(time == minTime){ os++; }else{ minTime = time ; os = 1 ; } } //5.根据id查询blog String idStr = StrUtil.join(",",ids); List blogs = query().in("id", ids).last("ORDER BY FIELD(id," + idStr + ")").list(); for (Blog blog : blogs) { //5.1 查询blog有关的用户 queryBlogUser(blog); //5.2 查询blog是否被点赞 isBlockLiked(blog); } //6 封装并返回 ScrollResult r = new ScrollResult(); r.setList(blogs); r.setOffset(os); r.setMinTime(minTime); return Result.ok(r); } private void queryBlogUser(Blog blog) { Long userId = blog.getUserId(); User user = userService.getById(userId); blog.setName(user.getNickName()); blog.setIcon(user.getIcon()); } }

你可能感兴趣的:(redis,笔记,缓存,java,后端)