Redis学习(六):使用BitMap实现用户签到
1. BitMap的常用命令
- SETBIT 向指定位置存入0或1
127.0.0.1:6379> SETBIT demo 0 1
(integer) 0
- GETBIT 获取指定位置的bit值
127.0.0.1:6379> GETBIT demo 0
(integer) 1
- BITFIELD 操作(修改、查询、自增)BitMap中bit数组中的指定位置的值
127.0.0.1:6379> BITFIELD demo GET u1 0 // BITFIELD key GET type offset -u 无符号 -i有符号
1) (integer) 1
127.0.0.1:6379> BITFIELD demo GET i1 0
1) (integer) -1
- BITCOUNT 统计BitMap中值为1的bit位数量
127.0.0.1:6379> BITCOUNT demo
(integer) 2
- BITPOS 查找bit数组中指定范围内第一个0或1出现的位置
127.0.0.1:6379> BITPOS demo 0
(integer) 1
2. 实现用户签到功能
将用户id和年月作为BitMap的key,将签到的记录保存到一个BitMap中,每次签到就修改对应位上的数字(0 -> 1)
@Override
public Result sign() {
// 1. 获取当前用户id
Long userId = UserHolder.getUser().getId();
// 2. 获取日期
LocalDateTime now = LocalDateTime.now();
// 3. 获取key
String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
String key = USER_SIGN_KEY + userId + keySuffix;
// 4. 得到今天是本月第几天
int dayOfMonth = now.getDayOfMonth();
// 5. 写入redis
stringRedisTemplate.opsForValue().setBit(key, dayOfMonth-1, true);
return Result.ok();
}
3. 连续签到统计
定义一个计数器,循环让签到数据(一个十进制的数)与1进行与运算,结果为1这表明签到了,让计数器+1,数据需要右移一位。结果为0表明连续签到断掉了,可以结束循环返回计数器结果了。
@Override
public Result signCount() {
// 1. 获取当前用户id
Long userId = UserHolder.getUser().getId();
// 2. 获取日期
LocalDateTime now = LocalDateTime.now();
// 3. 获取key
String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
String key = USER_SIGN_KEY + userId + keySuffix;
// 4. 得到今天是本月第几天
int dayOfMonth = now.getDayOfMonth();
// 5. 获取到截至现在所有的签到记录,返回的结果是十进制数字
List<Long> result = stringRedisTemplate.opsForValue().bitField(
key,
BitFieldSubCommands
.create()
.get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth))
.valueAt(0)
);
if (result == null || result.isEmpty()) {
// 没有任何签到结果
return Result.ok(0);
}
// 取出数据
Long num = result.get(0);
if (num == null || num == 0){
return Result.ok(0);
}
// 循环遍历
int count = 0;
while (true) {
// 与数字1相与,得到数字的最后一位的bit位
if ((num & 1) == 0) {
break;
}else{
count++;
}
// 将数字右移一位
num >>>= 1;
}
return Result.ok(count);
}
本文是原创文章,转载请注明来自 Lazyking.site
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果
Steam卡片