一)基于Set集合实现点赞功能:
在我们的博客表当中,每一篇博客信息都有一个like字段,表示点赞的数量
需求:
1)同一个用户只能点赞一次,再次进行点赞则会被取消;
2)如果当前用户已经点赞过了,那么点赞按钮高亮显示,这个是先是依靠前端来进行实现的,是通过判断Blog类的isLike属性;
实现步骤:
1)给Blog类中添加一个isLike字段,表示当前用户是否被当前用户点过赞,如果在前端判断这个isLike存在,那么说明用户点赞过,那么直接将用户按钮变亮,如果不存在那么直接变黑,我们其实可以再次创建一张表,这张表就去记录blogID和给这个Blog点赞的userID,那么每当点赞一次,这张表就纪录了一次;
2)修改点赞功能,利用Redis的Set集合判断是否被点赞过,没有点赞过那么点赞数+1,将用户ID存储到Set集合里面,如果已经点赞过,那么点赞数-1,将用户ID从Set集合中去除
3)在博客列表页和博客详情页里面,前端就要进行查询blog中的islike字段,来进行判断当前用户是否被点赞过
@RequestMapping @Controller public class UserController { @Autowired private StringRedisTemplate template; @Autowired private DemoMapper mapper; @RequestMapping("/Java100") @ResponseBody public void InsertLike(Integer userID,Integer blogID){ //1.正常情况下应该从session中获取到当前用户信息,此处为了方便实现直接从前端传递userID //2.判断当前用户是否已经针对这一篇文章点过赞了 String key="blog:liked"+blogID; Boolean flag=template.opsForSet().isMember(key,userID.toString()); if(!flag){ //1.如果查询不到,说明当前用户没有点过赞,没有点过赞,点赞数量+1 mapper.updateAddlike(blogID); //2.向redis中的set集合存放用户信息 template.opsForSet().add(key, String.valueOf(userID)); }else{ //1.如果查询到了,说明用户已经点过赞了,点赞数-1 mapper.updateSublike(blogID); //2.将用户ID从redis的有序集合中去除 template.opsForSet().remove(key,String.valueOf(userID)); } } public boolean islike(int blogID,int userID){ String key="blog:liked"+blogID; Boolean flag=template.opsForSet().isMember(key,String.valueOf(userID)); //最终这个返回值要被返回的blog中设置,blog就携带了这个islike信息,前端进行接收到这个islike信息的时候,如果为true,那么按钮变亮,如果为false,那么按钮置灰 return flag; } }
二)基于SortedSet或者list实现点赞排行榜,就是找到最新点赞的5个人
@RequestMapping @Controller public class UserController { @Autowired private StringRedisTemplate template; @Autowired private DemoMapper mapper; @RequestMapping("/Java100") @ResponseBody public String InsertLike(Integer userID,Integer blogID){ //1.正常情况下应该从session中获取到当前用户信息,此处为了方便实现直接从前端传递userID //2.判断当前用户是否已经针对这一篇文章点过赞了 String key="blog:liked:"+blogID; Double score=template.opsForZSet().score(key,userID.toString()); if(score==null){ //1.如果查询不到,说明当前用户没有点过赞,没有点过赞,点赞数量+1 mapper.updateAddlike(blogID); //2.向redis中的set集合存放用户信息,SortedSet的命令是zadd key value score template.opsForZSet().add(key,userID.toString(),System.currentTimeMillis()); return "点赞成功"; }else{ //1.如果查询到了,说明用户已经点过赞了,点赞数-1 mapper.updateSublike(blogID); //2.将用户ID从redis的有序集合中去除 template.opsForZSet().remove(key,String.valueOf(userID)); return "取消点赞成功"; } } public boolean islike(int blogID,int userID){ String key="blog:liked:"+blogID; Double score=template.opsForZSet().score(key,String.valueOf(userID)); if(score==null){ return false; } return true; } @RequestMapping("/Java300") @ResponseBody public List<Integer> getLastLikeUser(int blogID){ //1.先进行生成key String key="blog:liked:"+blogID; //2.查询redis中SoreedSet最先点赞的前五名,zrange key 0 4 Set<String> userIDs=template.opsForZSet().range(key,0,4); //3.解析到其中的用户ID,查找用户信息,封装到List集合中进行返回,正常是应该返回user信息的 List<Integer> list=new ArrayList<>(); userIDs.forEach(new Consumer<String>() { @Override public void accept(String s) { list.add(Integer.parseInt(s)); } }); return list; } }
二)实现关注和取消关注功能
接口1:请求格式:127.0.0.1:8080/Java100?userID=5&isFollow=true
这里面的userID表示被关注的人的ID,这里面的isFollow是表示是关注还是取关,关注就是true,取消关注就是false
接口2:查看登陆用户是否已经关注指定用户:
127.0.0.1:8080/IsFollow/10,10表示被指定的用户
@RequestMapping("/Follow/{userID}/{isFollow}") @ResponseBody public String Follow(@PathVariable("userID") Integer userID, @PathVariable("isFollow") Boolean isFollow, HttpSession session){ //1.判断到底是关注还是取关 User user= (User) session.getAttribute("user"); //2.关注直接新增数据,取关注解删除数据 if(isFollow){ //还应该在来进行判断一下当前follow是否存在,防止重复进行关注 Follow flag=mapper.selectFollow(user.getUserID(),userID); if(flag!=null){ return "当前您已经关注了,不能重复进行关注"; } Follow follow=new Follow(); follow.setFollowUserID(userID); follow.setUserID(user.getUserID()); mapper.InsertFollow(follow); return "关注成功"; }else{ int data=mapper.deleteFollow(user.getUserID(),userID); if(data==0) { return "取关成功"; }else{ return "不能重复取关"; } } } @RequestMapping("/IsFollow/{userID}") @ResponseBody public String IsFollow(@PathVariable("userID") Integer followedUserID,HttpSession session){ // 1.先获取到登录用户 User user= (User) session.getAttribute("user"); //2.判断用户是否关注 Follow follow=mapper.selectFollow(user.getUserID(),followedUserID); if(follow==null){ return "当前登录用户没有关注"; } return "当前用户已经关注了"; } @RequestMapping("/login") @ResponseBody public String login(String username,String password,HttpSession session){ User user=mapper.login(username,password); if(user!=null) { session.setAttribute("user",user); return "登陆成功"; } return "登陆失败"; }
三)实现共同关注功能
需求:基于redis的恰当的数据结构,来实现共同关注功能,在博主个人主页的展现出当前用户和博主的共同好友
首先应该把一个用户关注的列表保存到redis当中,比如说当前用户关注了那些人保存到redis集合中,目标用户关注了哪些人,也需要保存到redis集合里面,这样我们进行查找共同关注好友的时候,我们可以直接进行查询两个人共同关注的好友,直接取交集就可以了,所以我们应该又该以前的接口,每当我们关注到一个人的时候,我们都应该把他存放到Set集合里面,这样真正来进行查询共同关注的好友的时候,就十分方便了,关注的用户我们不光要把她存放到数据库里面,也需要把他存放到redis里面,key就是当前登陆用户的ID,value就是
当前登录用户所进行关注的用户的ID
程序传入指定的用户ID,程序就会查询这个用户ID和当前已经登陆过的用户的共同关注好友
1)进行改造过的JAVA代码:
@RequestMapping("/Follow/{userID}/{isFollow}") @ResponseBody public String Follow(@PathVariable("userID") Integer userID, @PathVariable("isFollow") Boolean isFollow, HttpSession session){ //1.判断到底是关注还是取关 User user= (User) session.getAttribute("user"); String key="follow:"+user.getUserID(); //2.关注直接新增数据,取关注解删除数据 if(isFollow){ //还应该在来进行判断一下当前follow是否存在,防止重复进行关注 Follow flag=mapper.selectFollow(user.getUserID(),userID); if(flag!=null){ return "当前您已经关注了,不能重复进行关注"; } Follow follow=new Follow(); follow.setFollowUserID(userID); follow.setUserID(user.getUserID()); mapper.InsertFollow(follow); //把当前被关注的用户ID存放到Set集合里面,zadd template.opsForSet().add(key,String.valueOf(follow.getFollowUserID())); return "关注成功"; }else{ int data=mapper.deleteFollow(user.getUserID(),userID); template.opsForSet().remove(key,String.valueOf(userID)); if(data==0) { return "取关成功"; }else{ return "不能重复取关"; } } }
2)现在用户进行查询
127.0.0.1:8080/common?userID=2
@RequestMapping("/common") @ResponseBody public List<Integer> GetCommon(Integer userID,HttpSession session){ //1.先生成key String key1="follow:"+userID; User user= (User) session.getAttribute("user"); String key2="follow:"+user.getUserID(); Set<String> set=template.opsForSet().intersect(key1,key2); if(set==null||set.isEmpty()){ return null; } //2.获取两人共同关注的好友 List<Integer> list=new ArrayList<>(); set.forEach(new Consumer<String>() { @Override public void accept(String s) { list.add(Integer.parseInt(s)); } }); return list; }