zoukankan      html  css  js  c++  java
  • 7_1_Redis实现赞踩功能

    一、实现需求

    1. 登录账号以后,在首页home.html内可以点赞或者取消赞,只能点赞一次,点赞以后就不可再点赞;

       取消赞以后为0.

    2 点开news以后也可以点赞或者取消赞。

    二.具体实现

    1  util包下写一个类似DAO的组件,组件类包括Jedis初始化,获取Jedis,Jedis的获取get,set,获取集合大小等操作。

    package com.nowcoder.util;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.stereotype.Service;
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisPool;
    import redis.clients.jedis.JedisPoolConfig;
    
    /**
     * Created by Administrator on 2017/5/1.
     */
    @Service
    public class JedisAdapter implements InitializingBean {
    
        private static final Logger logger = LoggerFactory.getLogger(JedisAdapter.class);
    
        private Jedis jedis = null;
        private JedisPool jedisPool = null;
    
        @Override
        public void afterPropertiesSet() throws Exception {
            //初始化
            jedisPool = new JedisPool("localhost", 6379);
        }
    
        //获取一个Jedis
        private Jedis getJedis(){
            try{
                jedis =  jedisPool.getResource();
            }catch (Exception e){
                logger.error("获取jedis失败!" + e.getMessage());
            }finally {
                if(jedis != null){
                    jedis.close();
                }
            }
            return jedis;
        }
    
        /**
         * 获取Redis中集合中某个key值
         * @param key
         * @return
         */
        public String get(String key){
            Jedis jedis = null;
            try {
                jedis =  jedisPool.getResource();
                return jedis.get(key);
            }catch (Exception e){
                logger.error("Jedis get发生异常 " + e.getMessage());
                return null;
            }finally {
                if(jedis != null){
                    jedis.close();
                }
            }
        }
    
        /**
         * 给Redis中Set集合中某个key值设值
         * @param key
         * @param value
         */
        public void set(String key, String value){
            Jedis jedis = null;
            try {
                jedis = jedisPool.getResource();
                jedis.set(key, value);
            }catch (Exception e){
                logger.error("Jedis set 异常" + e.getMessage());
            }finally {
                if(jedis != null){
                    jedis.close();
                }
            }
        }
    
        /**
         * 向Redis中Set集合添加值:点赞
         * @return
         */
        public long sadd(String key, String value){
            Jedis jedis = null;
            try{
                jedis =  jedisPool.getResource();
                return jedis.sadd(key, value);
            }catch (Exception e){
                logger.error("Jedis sadd 异常 :" + e.getMessage());
                return 0;
            }finally {
                if (jedis != null){
                    jedis.close();
                }
            }
        }
    
        /**
         * 移除:取消点赞
         * @param key
         * @param value
         * @return
         */
        public long srem(String key, String value){
            Jedis jedis = null;
            try{
                jedis =  jedisPool.getResource();
                return jedis.srem(key, value);
            }catch (Exception e){
                logger.error("Jedis srem 异常:" + e.getMessage());
                return 0;
            }finally {
                if (jedis != null){
                    jedis.close();
                }
            }
        }
    
        /**
         *p判断key,value是否是集合中值
         * @param key
         * @param value
         * @return
         */
        public boolean sismember(String key, String value){
            Jedis jedis = null;
            try{
                jedis =  jedisPool.getResource();
                return jedis.sismember(key, value);
            }catch (Exception e){
                logger.error("Jedis sismember 异常:" + e.getMessage());
                return false;
            }finally {
                if (jedis != null){
                    try{
                        jedis.close();
                    }catch (Exception e){
                        logger.error("Jedis关闭异常" + e.getMessage());
                    }
                }
            }
        }
    
        /**
         * 获取集合大小
         * @param key
         * @return
         */
        public long scard(String key){
            Jedis jedis = null;
            try{
                jedis =  jedisPool.getResource();
                return jedis.scard(key);
            }catch (Exception e){
                logger.error("Jedis scard 异常:" + e.getMessage());
                return 0;
            }finally {
                if (jedis != null){
                    jedis.close();
                }
            }
        }
    
    
    
    
    
    
    
    
    
    
    
    
    
    }
    View Code

    2 util包下写一个util工具类,实现点赞生成键key的值。

    package com.nowcoder.util;
    
    import org.springframework.stereotype.Service;
    
    /**
     * Created by Administrator on 2017/5/1.
     */
    public class RedisKeyUtil {
    
        private static String SPLIT = ":";
        private static String BIZ_LIKE = "LIKE";
        private static String BIZ_DISLIKE = "DISLIKE";
    
        /**
         * 产生key:如在newsId为2上的咨询点赞后会产生key: LIKE:ENTITY_NEWS:2
         * @param entityId
         * @param entityType
         * @return
         */
        public static String getLikeKey(int entityId, int entityType){
            return BIZ_LIKE + SPLIT + String.valueOf(entityType) + SPLIT + String.valueOf(entityId);
        }
        /**
         * 取消赞:如在newsId为2上的资讯取消点赞后会产生key: DISLIKE:ENTITY_NEWS:2
         * @param entityId
         * @param entityType
         * @return
         */
        public static String getDisLikeKey(int entityId, int entityType){
            return BIZ_DISLIKE + SPLIT + String.valueOf(entityType) + SPLIT + String.valueOf(entityId);
        }
    
    
    
    
    
    
    
    
    
    }
    View Code

    3 Service包下写上一个判断点赞还是反对的方法,当点赞后将当前点赞用户id存入likeKey集合中,同时从disLikeKey中移除此id:

    package com.nowcoder.service;
    
    import com.nowcoder.util.JedisAdapter;
    import com.nowcoder.util.RedisKeyUtil;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    /**
     * Created by Administrator on 2017/5/1.
     */
    @Service
    public class LikeService {
    
        @Autowired
        JedisAdapter jedisAdapter;
    
        /**
         * 判断是点赞还是点反对
         * @param userId
         * @param entityType
         * @param entityId
         * @return
         */
        public int getLikeStatus(int userId, int entityType, int entityId) {
            //根据当前用户的userid分别生成一个likeKey 和 disLikeKey,再分别判断这两个值是否在对应的Like集合中和disLikeKey集合中
            //比如如果在likeKey集合中,就返回一个1,否则返回-1
            String likeKey = RedisKeyUtil.getLikeKey(entityId, entityType);
            //判断值为userId 的用户是否在key为listKey 的集合中
            if(jedisAdapter.sismember(likeKey, String.valueOf(userId))){
                return 1;
            }
            String disLikeKey = RedisKeyUtil.getDisLikeKey(entityId, entityType);
            return jedisAdapter.sismember(disLikeKey, String.valueOf(userId)) ? -1: 0;
        }
    
        /**
         * 点赞:即当前用户点赞后,被点赞用户的like集合中就会加上一个该点赞的用户信息
         * @param userId
         * @param entityType
         * @param entityId
         * @return
         */
        public long like(int userId, int entityType, int entityId){
            //在当前news上点赞后获取key:   LIKE:ENTITY_NEWS:2
           String likeKey = RedisKeyUtil.getLikeKey(entityId, entityType);
           //在喜欢集合中添加当前操作用户的userId(即当前用户点赞后,被点赞用户的like集合中就会加上一个点赞的用户信息)
           jedisAdapter.sadd(likeKey, String.valueOf(userId));
    
           String disLikeKey = RedisKeyUtil.getDisLikeKey(entityId, entityType);
           jedisAdapter.srem(disLikeKey, String.valueOf(userId));
    
           //返回点赞数量
            return jedisAdapter.scard(likeKey);
        }
    
        /**
         * 反对 :即当前用户点反对后,被点反对用户的like集合中就会加上一个该点反对的用户信息
         * @param userId
         * @param entityType
         * @param entityId
         * @return
         */
        public long disLike(int userId, int entityType, int entityId){
    
            //谁点击反对,谁就出现在key为dislikeKey的Set集合中
            String disLikeKey = RedisKeyUtil.getDisLikeKey(entityId, entityType);
            jedisAdapter.sadd(disLikeKey, String.valueOf(userId));
    
            //从赞中删除
            String likeKey = RedisKeyUtil.getLikeKey(entityId, entityType);
            jedisAdapter.srem(likeKey, String.valueOf(userId));
    
            return jedisAdapter.scard(likeKey);
        }
    
    
    
    
    
    
    
    
    
    
    
    
    
    }
    View Code

    4 Controller: 调用LikeService,将当前用户id存入Redis的LikeKey集合中,并更新News表中 的like_count数量;对应的dislike也是一样。

    package com.nowcoder.controller;
    
    import com.nowcoder.model.EntityType;
    import com.nowcoder.model.HostHolder;
    import com.nowcoder.model.News;
    import com.nowcoder.service.LikeService;
    import com.nowcoder.service.NewsService;
    import com.nowcoder.util.ToutiaoUtil;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    /**
     * Created by Administrator on 2017/5/1.
     */
    @Controller
    public class LikeController {
    
        @Autowired
        LikeService likeService;
        @Autowired
        NewsService newsService;
        @Autowired
        HostHolder hostHolder;
    
        @RequestMapping(path = {"/like"}, method = {RequestMethod.GET, RequestMethod.POST})
        @ResponseBody
        public String like(@RequestParam("newsId") int newsId){
            //在newsId 的资讯上加入当前用户
            long likeCount = likeService.like(hostHolder.getUser().getId(), EntityType.ENTITY_NEWS, newsId);
    
            //更新点赞数
            //News news = newsService.getById(newsId);
            newsService.updateLikeCount(newsId, (int)likeCount);
    
            return ToutiaoUtil.getJSONString(0, String.valueOf(likeCount));
        }
    
        @RequestMapping(path = {"/dislike"}, method = {RequestMethod.POST, RequestMethod.GET})
        @ResponseBody
        public String disLike(@RequestParam("newsId") int newsId){
    
            //点击反对:调用disLike,将当前点击反对的用户id从key为dislikeKey的集合中移除
            long likeCount = likeService.disLike(hostHolder.getUser().getId(), EntityType.ENTITY_NEWS, newsId);
            if(likeCount <= 0){
                likeCount = 0;
            }
    
            //更新喜欢数
            newsService.updateLikeCount(newsId, (int)likeCount);
            return ToutiaoUtil.getJSONString(0, String.valueOf(likeCount));
        }
    
    
    }
    View Code

    5. NewsService:

      public int updateLikeCount(int newsId, int likeCount){
            return newsDao.updateLikeCount(newsId, likeCount);
        }

    NewsDao:

       @Update({"update", TABLE_NAME, "set like_count=#{likeCount} where id=#{newsId}"})
        int updateLikeCount(@Param("newsId") int newsId, @Param("likeCount") int likeCount);

    6. 同时HomeController中首页获取News上的点赞时,要加入判断。如果是未登录,点赞数全部为0;登录后就获取点赞的状态判断是点赞还是反对。

     if (localUserId != 0) {
                    vo.set("like", likeService.getLikeStatus(localUserId, EntityType.ENTITY_NEWS, news.getId()));
                } else {
                    vo.set("like", 0);
                }

    7. NewsController中的获取News详情页也要加入这样的判断:

  • 相关阅读:
    Ubuntu8.04代码已冻结发布在即
    Ruby on rails开发从头来(五十) ActiveRecord基础(更新记录)
    Ruby on rails开发从头来(四十四) ActiveRecord基础(创建记录)
    Ruby on rails开发从头来(四十五) ActiveRecord基础(读取记录)
    网络恶搞“白送家产”:美国男子回家发现财产被搬空
    Ruby on rails开发从头来(四十三) ActiveRecord基础(连接数据库)
    Ruby on rails开发从头来(四十九) ActiveRecord基础(行数和再加载数据)
    Ruby on rails开发从头来(四十七) ActiveRecord基础(强大的find方法)
    Ruby on rails开发从头来(四十六) ActiveRecord基础(SQL和Active Record)
    简单三步堵死SQL Server注入漏洞
  • 原文地址:https://www.cnblogs.com/noaman/p/6819247.html
Copyright © 2011-2022 走看看