Bug如山勤为径,代码似海苦作舟。友友们好,这里是苦瓜大王。今天学习的是黑马点评项目实战篇------达人探店部分的学习,进行了一系列秒杀优化之后,终于进入到相对轻松的章节啦!今天我们将完成达人探店功能。笔记如下,后续会一直更新黑马点评学习过程中的笔记、问题等,请多多支持哦!
文章目录
一、发布探店笔记
- 表分析

- 接口分析

- 修改一下保存文件的位置,改成自己的目录,比如我的是D:\nginx-pro\nginx-hmdp-1.18.0\html\hmdp\imgs

二、查看探店笔记
- 接口分析

- 给Blog类加上两个属性
java
/**
* 用户图标
*/
@TableField(exist = false) //代表这个属性不属于数据库
private String icon;
/**
* 用户姓名
*/
@TableField(exist = false)
private String name;
- BlogController代码
java
------------------------------------BlogController---------------------------------------
@GetMapping("/hot")
public Result queryHotBlog(@RequestParam(value = "current", defaultValue = "1") Integer current) {
return blogService.queryHotBlog(current);
}
@GetMapping("/{id}")
public Result queryBlogById(@PathVariable("id") Long id) {
return blogService.queryBlogById(id);
}
- BlogServiceImpl代码
java
------------------------------------BlogServiceImpl--------------------------------------
@Resource
private IUserService userService;
/**
* 查询博文详情
* @param id
* @return
*/
public Result queryBlogById(Long id) {
//1.查询blog
Blog blog = getById(id);
if(blog==null)
return Result.fail("该Blog不存在!");
queryBlogUser(blog);
return Result.ok(blog);
}
/**
* 查询热点博文
* @param current
* @return
**/
@Override
public Result queryHotBlog(Integer current) {
// 根据用户查询
Page<Blog> page = query()
.orderByDesc("liked")
.page(new Page<>(current, SystemConstants.MAX_PAGE_SIZE));
// 获取当前页数据
List<Blog> records = page.getRecords();
// 查询用户
records.forEach(this::queryBlogUser);
return Result.ok(records);
}
/**
* 查询blog用户并封装属性进blog
* @param blog
*/
private void queryBlogUser(Blog blog) {
Long userId = blog.getUserId();
User user = userService.getById(userId);
blog.setName(user.getNickName());
blog.setIcon(user.getIcon());
}
三、点赞功能

1.业务思路

2.具体实现
(1)给Blog添加一个isLike字段
java
/**
* 是否点赞过了
*/
@TableField(exist = false)
private Boolean isLike;
(2)利用Redis的set集合修改点赞功能
java
-------------------------------------BlogServiceImpl-------------------------------------
@Resource
private StringRedisTemplate stringRedisTemplate;
/**
* 点赞博文
* @param id
* @return
*/
public Result likeBlog(Long id) {
//1.获取登录用户
Long userId= UserHolder.getUser().getId();
//2.判断当前登录用户是否已经点赞
String key = BLOG_LIKED_KEY + 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集合中
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集合中移除用户信息
if(isSuccess){
stringRedisTemplate.opsForSet().remove(key,userId.toString());
}
}
return Result.ok();
}
(3)修改两个查询Blog的业务,判断赋值isLike字段
- 增加判断是否点赞过方法
java
/**
* 判断是否点赞过
*/
public void isLikedBlog(Blog blog){
//1.获取登录用户
Long userId= UserHolder.getUser().getId();
//2.判断当前登录用户是否已经点赞
String key = BLOG_LIKED_KEY +blog.getId();
Boolean isMember = stringRedisTemplate.opsForSet().isMember(key, userId.toString());
blog.setIsLike(BooleanUtil.isTrue(isMember));
}
- 修改查询Blog的业务
java
/**
* 查询博文详情
* @param id
* @return
*/
public Result queryBlogById(Long id) {
//1.查询blog
Blog blog = getById(id);
if(blog==null)
return Result.fail("该Blog不存在!");
queryBlogUser(blog);
islIkeBlog(blog);
return Result.ok(blog);
}
/**
* 查询热点博文
* @param current
* @return
*/
public Result queryHotBlog(Integer current) {
// 根据用户查询
Page<Blog> page = query()
.orderByDesc("liked")
.page(new Page<>(current, SystemConstants.MAX_PAGE_SIZE));
// 获取当前页数据
List<Blog> records = page.getRecords();
// 查询用户
records.forEach(blog->{
this.queryBlogUser(blog);
this.islIkeBlog(blog);
});
return Result.ok(records);
}
小贴士:
- 要记得修改拦截器配置,把blog/hot拦截了,不然线程不会保存请求的user
四、点赞排行

- 用查分数的形式,查到就说明存在,查不到就说明不存在
1.用sortedSet改造点赞
(1)改造点赞业务
- 保存进sortSet
java
stringRedisTemplate.opsForZSet().add(key,userId.toString(),System.currentTimeMillis());
- 删除
java
stringRedisTemplate.opsForZSet().remove(key,userId.toString());
- 查是否存在
java
Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString());
if(score==null) {}
- 优化后点赞功能整体代码
java
/**
* 点赞博文
* @param id
* @return
*/
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保存用户信息到sortedSet集合中
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集合中移除用户信息
if(isSuccess){
stringRedisTemplate.opsForZSet().remove(key,userId.toString());
}
}
return Result.ok();
}
(2)改造查询业务
java
Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString());
blog.setIsLike(score!=null);
- 判断是否点赞过代码
java
/**
* 判断是否点赞过
*/
public void isLikedBlog(Blog blog){
//1.获取登录用户
Long userId= UserHolder.getUser().getId();
//2.判断当前登录用户是否已经点赞
String key = BLOG_LIKED_KEY +blog.getId();
Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString());
blog.setIsLike(score!=null);
}
2.点赞排行的实现
- 排行榜的顺序反了,是因为数据库查询的时候用了IN
- 需要手动指定顺序

- 对查询继续进行改造
java
-----------------------------------queryBlogLikes----------------------------------------
List<Long> ids = top5.stream().map(Long::valueOf).collect(Collectors.toList());
String idStr = StrUtil.join(",", ids);
// 3.根据用户id查询用户 WHERE id IN ( 5 , 1 ) ORDER BY FIELD(id, 5, 1)List<UserDTO> 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代码
java
/**
* 判断是否点赞过
*/
public void isLikedBlog(Blog blog){
//1.获取登录用户
UserDTO userDTO= UserHolder.getUser();
if(userDTO==null)
//用户未登录,无需查询是否点过赞
return;
Long userId = userDTO.getId();
//2.判断当前登录用户是否已经点赞
String key = BLOG_LIKED_KEY +blog.getId();
Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString());
blog.setIsLike(score!=null);
}
- 完整代码如下:
java
-----------------------------------BlogController----------------------------------------
@GetMapping("/likes/{id}")
public Result queryBlogLikes(@PathVariable("id") Long id) {
return blogService.queryBlogLikes(id);
}
----------------------------------BlogServiceImpl----------------------------------------
/**
* 查询博文点赞排行
* @param id
* @return
*/
public Result queryBlogLikes(Long id) {
String key = BLOG_LIKED_KEY + id;
// 1.查询top5的点赞用户 zrange key 0 4 Set<String> top5 = stringRedisTemplate.opsForZSet().range(key, 0, 4);
if (top5 == null || top5.isEmpty()) {
return Result.ok(Collections.emptyList());
}
// 2.解析出其中的用户id
List<Long> ids = top5.stream().map(Long::valueOf).collect(Collectors.toList());
String idStr = StrUtil.join(",", ids);
// 3.根据用户id查询用户 WHERE id IN ( 5 , 1 ) ORDER BY FIELD(id, 5, 1) List<UserDTO> 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);
}
以上就是黑马点评实战篇------达人探店部分的学习笔记,仅供参考,多多支持!🌹