<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
探店筆記類似點評網站的評價,往往是圖文結合。對應的表有兩個
先上傳圖片請求一次儲存圖片介面,再點發布請求釋出介面。這兩個介面已經寫好
BlogController
@RestController @RequestMapping("/blog") public class BlogController { @Resource private IBlogService blogService; @GetMapping("/hot") public Result queryHotBlog(@RequestParam(value = "current", defaultValue = "1") Integer current) { return blogService.queryHotBlog(current); } @GetMapping("/{id}") public Result queryBlogById(@PathVariable("id") String id){ return blogService.queryBlogById(id); } }
IBlogService
public interface IBlogService extends IService<Blog> { Result queryBlogById(String id); Result queryHotBlog(Integer current); }
BlogServiceImpl
@Service public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements IBlogService { @Autowired private IUserService userService; @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); } private void queryBlogUser(Blog blog) { Long userId = blog.getUserId(); User user = userService.getById(userId); blog.setName(user.getNickName()); blog.setIcon(user.getIcon()); } @Override public Result queryBlogById(String id) { Blog blog = getById(id); if(blog == null){ return Result.fail("筆記不存在!"); } queryBlogUser(blog); return Result.ok(blog); } }
現在已經寫好的點贊介面
問題:這樣寫介面,可以一直按點贊重複點贊
需求
實現步驟
業務實現
@RestController @RequestMapping("/blog") public class BlogController { @Resource private IBlogService blogService; @PutMapping("/like/{id}") public Result likeBlog(@PathVariable("id") Long id) { return blogService.likeBlog(id); } @GetMapping("/hot") public Result queryHotBlog(@RequestParam(value = "current", defaultValue = "1") Integer current) { return blogService.queryHotBlog(current); } @GetMapping("/{id}") public Result queryBlogById(@PathVariable("id") String id){ return blogService.queryBlogById(id); } }
編寫完點贊操作的介面後還要修改之前的查詢介面,增加查詢是否已經點贊
@Service public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements IBlogService { @Autowired private IUserService userService; @Autowired private StringRedisTemplate stringRedisTemplate; @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(blog -> { this.queryBlogUser(blog); this.isBlogLiked(blog); }); return Result.ok(records); } @Override public Result likeBlog(Long id) { // 1、獲取登入使用者 UserDTO user = UserHolder.getUser(); // 2、判斷當前登入使用者是否已經點贊 Boolean isMember = stringRedisTemplate.opsForSet().isMember(RedisConstants.BLOG_LIKED_KEY + id, user.getId().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(RedisConstants.BLOG_LIKED_KEY + id, user.getId().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(RedisConstants.BLOG_LIKED_KEY + id, user.getId().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()); } @Override public Result queryBlogById(String id) { Blog blog = getById(id); if(blog == null){ return Result.fail("筆記不存在!"); } queryBlogUser(blog); // 查詢 Blog 是否被點贊 isBlogLiked(blog); return Result.ok(blog); } private void isBlogLiked(Blog blog) { Long userId = blog.getUserId(); String key = RedisConstants.BLOG_LIKED_KEY + blog.getId(); Boolean isMember = stringRedisTemplate.opsForSet().isMember(key, userId.toString()); blog.setIsLike(BooleanUtil.isTrue(isMember)); } }
查出給這個筆記點讚的人,類似微信朋友圈的點贊,可以展示誰點讚了,而且我們要進行排序
所以我們得用SortedSet這種資料型別
把原本存入set改為存入zset多加個分數,分數就是時間戳
@Override public Result likeBlog(Long id) { // 1、獲取登入使用者 UserDTO user = UserHolder.getUser(); // 2、判斷當前登入使用者是否已經點贊 Double score = stringRedisTemplate.opsForZSet().score(RedisConstants.BLOG_LIKED_KEY + id, user.getId().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){ // 時間作為 key 的 score stringRedisTemplate.opsForZSet().add(RedisConstants.BLOG_LIKED_KEY + id, user.getId().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(RedisConstants.BLOG_LIKED_KEY + id, user.getId().toString()); } } return Result.ok(); }
然後是否被點讚的方法也要修改,根據key取出分數,分數不為null就是點贊過了
private void isBlogLiked(Blog blog) { UserDTO user = UserHolder.getUser(); if(user == null){ return; } Long userId = user.getId(); String key = RedisConstants.BLOG_LIKED_KEY + blog.getId(); Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString()); blog.setIsLike(score != null); }
需求:實現前五個點讚的使用者返回
我們先用動態id去redis中查詢出前五個點贊使用者的id
然後根據id去資料庫中查詢資訊封裝到dto再返回
@GetMapping("/likes/{id}") public Result queryBlogLikes(@PathVariable("id") String id) { return blogService.queryBlogLikes(id); }
@Override public Result queryBlogLikes(String id) { String key = RedisConstants.BLOG_LIKED_KEY + id; // 查詢 top5 的點贊使用者 Set<String> top5 = stringRedisTemplate.opsForZSet().range(key, 0, 4); if(top5 == null){ return Result.ok(Collections.emptyList()); } // 解析出其中的使用者id List<Long> ids = top5.stream().map(Long::valueOf).collect(Collectors.toList()); String join = StrUtil.join(",", ids); // 根據使用者id查詢使用者 List<UserDTO> userDTOS = userService.query().in("id", ids).last("order by filed(id, "+join+")").list() .stream() .map(user -> BeanUtil.copyProperties(user, UserDTO.class)) .collect(Collectors.toList()); return Result.ok(userDTOS); }
注意:如果我們mp直接用in來查詢根本不能保證點讚的順序,因為in查詢出來的是按照id順序返回的,沒有排序,我們要按照查詢id的順序來查,order by field(id,5,1)這樣
到此這篇關於Redis筆記點贊排行榜的實現範例的文章就介紹到這了,更多相關Redis筆記點贊內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45