4.2 点赞和我收到的赞

点赞

编写返回点赞key的工具

某个实体的赞,需要传入实体的类型,实体id

public class RedisKeyUtill {
    private static final String SPILT=":";
    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+SPILT+entityType+SPILT+entityId;
    }
}

编写Service实现点赞业务

  • 集合的元素是不重复的,所有可以根据userId找到对应的唯一用户,根据用户的数量可以得出点赞的数量
  • 集合的key是每一个实体对应的唯一key 比如传入帖子id,这个帖子就生成了一个唯一key
  • 判断用户有没有点过赞 看集合里有没有对应的userId 如果已经点赞就移除该用户,取消赞
@Service
public class LikeService {
    @Autowired
    RedisTemplate redisTemplate;

    //点赞业务
    public void Like(int userId,int entityType,int entityId)
    {
        //获取key  例如获取指定id帖子的key
        String entityLikeKey= RedisKeyUtill.getEntityLikeKey(entityType,entityId);
        //判断该用户是否已经点过赞
        if(redisTemplate.opsForSet().isMember(entityLikeKey,userId))
        {
            redisTemplate.opsForSet().remove(entityLikeKey,userId);
        }else {
            redisTemplate.opsForSet().add(entityLikeKey,userId);
        }

    }

    // 查询某实体点赞的数量
    public long findEntityLikeCount(int entityType, int entityId) {
        //获取key  例如获取指定id帖子的key
        String entityLikeKey= RedisKeyUtill.getEntityLikeKey(entityType,entityId);
        return redisTemplate.opsForSet().size(entityLikeKey);

    }

    // 查询某人对某实体的点赞状态
    public int findEntityLikeStatus(int userId, int entityType, int entityId) {
        //获取key  例如获取指定id帖子的key
        String entityLikeKey= RedisKeyUtill.getEntityLikeKey(entityType,entityId);
        return redisTemplate.opsForSet().isMember(entityLikeKey,userId)?1:0;
    }
}

编写Controller

@Controller
public class LikeController {

    @Autowired
    private LikeService likeService;

    @Autowired
    private HostHolder hostHolder;


    //点赞是异步请求,需要返回JSON字符串
    @RequestMapping(path = "/like", method = RequestMethod.POST)
    @ResponseBody
    public String like(int entityType, int entityId) {
        User user = hostHolder.getUser();
        //点赞
        likeService.Like(user.getId(),entityType,entityId);

        // 数量
        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);

    }

}

修改页面

处理异步请求 把超链接当做按钮来用 编写js 拼接变量

this 知道哪一个赞 处理三个地方的赞

新建js文件

<a href="javascript:;" th:onclick="|like(this,1,${post.id});|" class="text-primary">
   <b th:text="${likeStatus==1?'已赞':'赞'}">赞</b> <i th:text="${likeCount}">11</i>
</a>
function like(btn,entityType,entityId) {
    $.post(
        CONTEXT_PATH+"/like",
        {"entityType":entityType,"entityId":entityId},
        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);
            }
        }
    )

}

2、修改主页帖子点赞的数量

@RequestMapping(value = "/index",method = RequestMethod.GET)
public String getIndexPage(Model model, Page page)
{
    //不需要向model中添加page对象  因为方法调用前,SpringMvc会自动实例化Model和Page,并将Page注入Model
    // 所以,在Thymeleaf中可以直接访问Page对象中的数据
    //获取总行数
    page.setRows(discussPostService.countDiscussPosts(0));
    page.setPath("/index");

    //获取帖子数据
    List<DiscussPost> list = discussPostService.findDiscussPosts(0, page.getOffset(),page.getLimit());
    //创建新集合
    List<Map<String,Object>> discussPosts=new ArrayList<>();
    //遍历list
    if(list!=null)
    {
        for(DiscussPost post:list)
        {
            Map<String,Object> map=new HashMap<>();
            map.put("post",post);
            User user = userService.queryUserById(post.getUserId());
            map.put("user",user);

            //查询帖子点赞的数量
            long entityLikeCount = likeService.findEntityLikeCount(post.getType(), post.getId());
            map.put("likeCount",entityLikeCount);

            discussPosts.add(map);
        }
    }
    model.addAttribute("discussPosts",discussPosts);
    return "/index";
}
<li class="d-inline ml-2" >赞 <span th:text="${map.likeCount}">11</span></li>

3、修改每个帖子详情,每个评论,每个回复点赞的数量和状态

//点赞数量
long entityLikeCount = likeService.findEntityLikeCount(ENTITY_TYPE_POST, id);
model.addAttribute("likeCount",entityLikeCount);

//点赞状态
int likeStatus=hostHolder.getUser()==null?0:
        likeService.findEntityLikeStatus(hostHolder.getUser().getId(),ENTITY_TYPE_POST,id);
model.addAttribute("likeStatus",likeStatus);

我收到的赞

重构点赞功能

以用户id为key来存放到Redis中,重构点赞功能,点赞的时候传入被赞人的用户id,如果是点赞就使该key的count加一,如果是取消赞就使被点赞人的key的值减

使用Redis事务

获取被赞人的id 不使用通过实体获取userid的方法,需要访问数据库 与redis的高性能相反

传入参数被赞人id 把查询放在事务之外

// 点赞
public void like(int userId, int entityType, int entityId, int entityUserId) {
    redisTemplate.execute(new SessionCallback() {
        @Override
        public Object execute(RedisOperations operations) throws DataAccessException {
            String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);
            String userLikeKey = RedisKeyUtil.getUserLikeKey(entityUserId);
            //判断用户是否已经点赞
            boolean isMember = operations.opsForSet().isMember(entityLikeKey, userId);

            operations.multi();

            if (isMember) {
                //如果已经点赞 移除赞
                //被点赞的用户的count减一
                operations.opsForSet().remove(entityLikeKey, userId);
                operations.opsForValue().decrement(userLikeKey);
            } else {
                //没有点赞
                //被点赞的用户的count加一
                operations.opsForSet().add(entityLikeKey, userId);
                operations.opsForValue().increment(userLikeKey);
            }
            return operations.exec();
        }
    });
}
 // 查询某个用户获得的赞
    public int findUserLikeCount(int userId) {
        String userLikeKey = RedisKeyUtil.getUserLikeKey(userId);
        Integer count = (Integer) redisTemplate.opsForValue().get(userLikeKey);
        return count == null ? 0 : count.intValue();
    }

个人主页

// 个人主页
@RequestMapping(path = "/profile/{userId}", method = RequestMethod.GET)
public String getProfilePage(@PathVariable("userId") int userId, Model model) {
    User user = userService.queryUserById(userId);
    if (user == null) {
        throw new RuntimeException("该用户不存在!");
    }

    // 用户
    model.addAttribute("user", user);
    // 点赞数量
    int likeCount = likeService.findUserLikeCount(userId);
    model.addAttribute("likeCount", likeCount);


    return "/site/profile";
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值