用户表有数字的唯一字段情况下用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"); } }
运行结果如下: