用户表有数字的唯一字段情况下用Redis的BitMap实现点赞功能(不能保存数据)
用户ID为数字的情况下用redis bitmaps实现点赞功能
需求如下:
1.点赞
2.取消点赞
3.查看是否点赞
4.统计有多少点赞
1.BitMap简介
(1)BitMap是一连串的二进制数字(0,1),每一位所在的位置为偏移(offset),在BitMap上可以执行AND,OR,XOR以及其他操作。
(2)位图计数
位图计数的意思是统计BitMap中值为1的位的个数,位图计数的效率是很高的。
(3)Redis BitMap
Redis中允许使用二进制的Key和二进制的Value,BitMap就是二进制的Value。
2.需求实现
(1)点赞/取消点赞
假设用户的数字Id为123456L,对textId为text1的微博点赞。首先根据textId生成赞数据存储的Redis key,比如生成策略为praise_{textId},userId为123456L的用户点赞,只需要将praise_text1的第123456位置为1即可(取消赞则置为0)。
(2)是否点赞
就是根据key和偏移量的值来查询对应的值是1还是0.查询userId为123456L的用户是否给praise_text1点赞,就只需查询praise_text1的第123456位置是否为1即可。
(3)统计有多少点赞
就是利用位图计数的原理来实现。
Jedis把很多方法都封装好了,理解了BitMap的思想后代码实现就是非常简单的了。
import redis.clients.jedis.Jedis;
/**
* @Author Zhongger
* @Description
* @Date 2020.3.19
*/
public class RedisDriver {
private Jedis jedis=null;
public RedisDriver(){
jedis=new Jedis("localhost",6379);
jedis.auth("123456");
}
/**
* 点赞
* @param textId 内容id
* @param userId 用户id
*/
public void praise(String textId,Long userId){
jedis.setbit("praise_" + textId, userId, true);
System.out.println(userId+"给"+textId+"点赞");
}
/**
* 取消赞
* @param textId 内容id
* @param userId 用户id
*/
public void unPraise(String textId,Long userId){
jedis.setbit("praise_" + textId, userId, false);
System.out.println(userId+"取消了"+textId+"的点赞");
}
/**
* 是否点赞
* @param textId 内容id
* @param userId 用户id
* @return true/false
*/
public boolean isPraise(String textId, Long userId){
Boolean flag = jedis.getbit("praise_" + textId, userId);
System.out.println(userId+"给"+textId+"点赞了吗?"+flag);
return flag;
}
/**
* 查询点赞次数
* @param textId 内容id
* @return 一个text被点赞的次数
*/
public Long praiseCount(String textId){
Long bitcount = jedis.bitcount("praise_" + textId);
System.out.println(textId+"的点赞数为"+bitcount);
return bitcount;
}
public static void main(String[] args) {
RedisDriver driver = new RedisDriver();
driver.praise("text1",123456L);
driver.unPraise("text1",123456L);
driver.praise("text1",10000L);
driver.praise("text1",10002L);
driver.praiseCount("text1");
}
}
运行结果如下: