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);
            }
        }
    );
}
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现朋友圈的点功能,可以借助 Redis 的数据结构和操作来实现。以下是一个简单的示例: 1. 使用 Redis 的有序集合(sorted set)存储每条朋友圈动态的点信息。每个动态对应一个有序集合,集合的成员是用户ID,分值是点的时间戳。例如,动态ID为 post_id 的点集合可以使用键名 `post:likes:post_id`。 2. 当用户给某条动态点时,可以使用 Redis 的命令 `ZADD` 将用户ID及点时间戳添加到相应的有序集合中。例如,用户ID为 user_id 的用户给动态ID为 post_id 的动态点,可以执行命令 `ZADD post:likes:post_id timestamp user_id`。 3. 当需要查询某条动态的点数时,可以使用 Redis 的命令 `ZCARD` 获取有序集合的成员数量。例如,查询动态ID为 post_id 的动态的点数,可以执行命令 `ZCARD post:likes:post_id`。 4. 当需要判断某个用户是否给某条动态点时,可以使用 Redis 的命令 `ZSCORE` 判断用户ID是否存在于相应的有序集合中,并获取其点时间戳。例如,判断用户ID为 user_id 的用户是否给动态ID为 post_id 的动态点,可以执行命令 `ZSCORE post:likes:post_id user_id`,如果返回非空值,则表示用户已经点。 值得注意的是,上述示例中的键名和命令仅供参考,你可以根据自己的实际需求进行调整和扩展。此外,由于 Redis 的数据存储在内存中,适用于高性能的读写操作,但需要根据实际情况来考虑数据的持久化和缓存策略。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值