Redis

关注公众号 jb51net

关闭
首页 > 数据库 > Redis > redis点赞状态和数量

redis实现存储帖子的点赞状态和数量的示例代码

作者:退役熬夜冠军选手

使用Redis来实现点赞功能是一种高效的选择,因为Redis是一个内存数据库,适用于处理高并发的数据操作,这篇文章主要介绍了redis实现存储帖子的点赞状态和数量的示例代码,需要的朋友可以参考下

redis实现存储帖子的点赞状态和数量

1 对redis进行配置并封装一个redis工具类

@Configuration //编写redis的配置类
public class RedisConfig {
    @Bean //参数声明了连接工厂
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        // 设置key的序列化方式
        template.setKeySerializer(RedisSerializer.string());
        // 设置value的序列化方式
        template.setValueSerializer(RedisSerializer.json());
        // 设置hash的key的序列化方式
        template.setHashKeySerializer(RedisSerializer.string());
        // 设置hash的value的序列化方式
        template.setHashValueSerializer(RedisSerializer.json());
           //让设置生效
        template.afterPropertiesSet();
        return template;
    }
}
public class RedisKeyUtil {
    private static final String SPLIT = ":";
    private static final String PREFIX_ENTITY_LIKE = "like:entity";
    // 某个实体的赞
    // like:entity:entityType:entityId -> set(userId)
    public static String getEntityLikeKey(int entityType, int entityId) {
        return PREFIX_ENTITY_LIKE + SPLIT + entityType + SPLIT + entityId;
    }
    }

2 reids操作起来比较简单,所以一般不需要写dao层,直接在service里面对数据进行操作

@Service
public class LikeService {
    @Autowired
    private RedisTemplate redisTemplate;
    // 点赞  谁点的赞 点赞的实体 实体的id 实体的用户
    public void like(int userId, int entityType, int entityId, ) {
        redisTemplate.execute(new SessionCallback() {
            @Override
            public Object execute(RedisOperations operations) throws DataAccessException {
                String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);
                boolean isMember = operations.opsForSet().isMember(entityLikeKey, userId);
                   //是否已经点过赞
                if (isMember) { //移除userid
                    operations.opsForSet().remove(entityLikeKey, userId);
                    operations.opsForValue().decrement(userLikeKey);
                } else { //添加userid
                    operations.opsForSet().add(entityLikeKey, userId);
                    operations.opsForValue().increment(userLikeKey);
                }
            }
        });
    }
    // 查询某实体点赞的数量
    public long findEntityLikeCount(int entityType, int entityId) {
        String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);
        return redisTemplate.opsForSet().size(entityLikeKey);
    }
    // 查询某人对某实体的点赞状态
    public int findEntityLikeStatus(int userId, int entityType, int entityId) {
        String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);
        //1表示点赞 0表示没有
        return redisTemplate.opsForSet().isMember(entityLikeKey, userId) ? 1 : 0;
    }

3controller层接受post请求带来的参数,将查询到的数据放进map里,传给前端回调函数,处理前端页面

@Controller
public class LikeController {
    @Autowired
    private LikeService likeService;
    @Autowired
    private HostHolder hostHolder;
    @RequestMapping(path = "/like", method = RequestMethod.POST)
    @ResponseBody
    public String like(int entityType, int entityId, int entityUserId) {
        User user = hostHolder.getUser();
        // 点赞
        likeService.like(user.getId(), entityType, entityId, entityUserId);
        // 数量
        long likeCount = likeService.findEntityLikeCount(entityType, entityId);
        // 状态
        int likeStatus = likeService.findEntityLikeStatus(user.getId(), entityType, entityId);
        // 返回的结果
        Map<String, Object> map = new HashMap<>();
        map.put("likeCount", likeCount);
        map.put("likeStatus", likeStatus);
        return CommunityUtil.getJSONString(0, null, map);
    }
}
//回调函数
function like(btn, entityType, entityId, entityUserId) {
    $.post(
        CONTEXT_PATH + "/like",
        {"entityType":entityType,"entityId":entityId,"entityUserId":entityUserId},
        function(data) {
            data = $.parseJSON(data);
            if(data.code == 0) {
                $(btn).children("i").text(data.likeCount);
                $(btn).children("b").text(data.likeStatus==1?'已赞':"赞");
            } else {
                alert(data.msg);
            }
        }
    );
}

使用Redis来实现点赞功能的基本思路

使用Redis来实现点赞功能是一种高效的选择,因为Redis是一个内存数据库,适用于处理高并发的数据操作。以下是一个基本的点赞功能在Redis中的设计示例:

假设我们有一个文章或帖子,用户可以对其进行点赞,取消点赞,以及查看点赞总数。

存储点赞信息:

使用Redis的Hash数据结构来存储每篇文章的点赞信息。每篇文章对应一个Hash,Hash的字段表示用户ID,字段值表示点赞状态(例如1代表已点赞,0代表未点赞)(值也可以存放用户点赞时间)。

HSET article_likes:<article_id> <user_id> 1

记录点赞总数:

使用 Redis 的 Set 数据结构来存储每篇文章的点赞用户集合,用于查询文章的点赞数量。每篇文章对应一个 Set,其中的元素为用户ID。

SADD article_likes_count:<article_id> <user_id>

取消点赞:

取消点赞时,从Hash中删除用户的点赞记录,同时从对应的 Set 中删除用户ID。

HDEL article_likes:<article_id> <user_id>
SREM article_likes_count:<article_id> <user_id>

查询点赞状态:

查询某篇文章的点赞状态,只需要查询对应的Hash数据结构中的字段值。

HGET article_likes:<article_id> <user_id>

查询点赞总数:

查询某篇文章的点赞总数,使用Redis的PFCount命令来统计HyperLogLog的数量。

SCARD article_likes_count:<article_id>

这只是一个简单的Redis设计示例。在实际应用中,您可能还需要考虑数据过期策略、持久化选项、缓存更新机制等等。另外,确保对Redis进行适当的配置和优化,以满足您应用的性能和可靠性需求。

到此这篇关于redis实现存储帖子的点赞状态和数量的文章就介绍到这了,更多相关redis点赞状态和数量内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文