点赞功能的设计

点赞功能的设计

每一次点赞,需要记录:

(1)谁点的赞;

(2)为哪篇文章(Convention)点的赞;

(3)点赞时间

(4)是否已经取消点赞

 

数据表设计

点赞记录表

列名

数据类型

说明

id

N

数据表id

user_id

N

用户id

vote_time

S

点赞时间,格式”2016-02-22 12:01:45”

bbs_id

N

被点赞帖子id

status

N

状态:有效或取消

 

继续讨论E-R关系

点赞记录表与用户是多对1关系

点赞记录表与帖子也是多对1关系

实体类:

package com.girltest.entity;

import java.util.List;

import javax.persistence.*;

import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

/**
 * Created by huangweii on 2016/2/21.
 */
@Entity
@Table(name = "t_vote_log")
public class VoteLog {
    private int id;
    private User user;
    /**
     * 点赞的时间
     */
private String voteTime;
    private int status;
   /**
    * 帖子
    */
private Convention convention;
    
    @Id
    @GeneratedValue
public int getId() {
      return id;
   }
   public void setId(int id) {
      this.id = id;
   }

   @ManyToOne
   @JoinColumn (name="userId")
   public User getUser() {
      return user;
   }
   public void setUser(User user) {
      this.user = user;
   }
   @Column(name = "vote_time")
   public String getVoteTime() {
      return voteTime;
   }
   public void setVoteTime(String voteTime) {
      this.voteTime = voteTime;
   }
   public int getStatus() {
      return status;
   }
   public void setStatus(int status) {
      this.status = status;
   }

   @ManyToOne
   @JoinColumn (name="conventionId")
   public Convention getConvention() {
      return convention;
   }

   public void setConvention(Convention convention) {
      this.convention = convention;
   }
}

 

 投票的控制器:

Java代码   收藏代码
  1. package com.girltest.web.controller;  
  2.   
  3. import com.common.dict.Constant2;  
  4. import com.common.util.SystemHWUtil;  
  5. import com.girltest.dao.ConventionDao;  
  6. import com.girltest.dao.Test2BoyDao;  
  7. import com.girltest.dao.VoteLogDao;  
  8. import com.girltest.entity.Convention;  
  9. import com.girltest.entity.User;  
  10. import com.girltest.entity.VoteLog;  
  11. import com.io.hw.json.HWJacksonUtils;  
  12. import com.time.util.TimeHWUtil;  
  13. import oa.util.AuthenticateUtil;  
  14. import oa.web.controller.base.BaseController;  
  15. import org.springframework.stereotype.Controller;  
  16. import org.springframework.ui.Model;  
  17. import org.springframework.web.bind.annotation.RequestMapping;  
  18. import org.springframework.web.bind.annotation.ResponseBody;  
  19.   
  20. import javax.annotation.Resource;  
  21. import javax.servlet.http.HttpServletRequest;  
  22. import javax.servlet.http.HttpSession;  
  23. import java.io.IOException;  
  24. import java.util.HashMap;  
  25. import java.util.Map;  
  26.   
  27. @Controller  
  28. @RequestMapping("/vote")  
  29. public class VoteController extends BaseController<VoteLog> {  
  30.     private VoteLogDao voteLogDao;  
  31.     private ConventionDao conventionDao;  
  32.     private Test2BoyDao test2BoyDao;  
  33.   
  34.   
  35.     public VoteLogDao getVoteLogDao() {  
  36.         return voteLogDao;  
  37.     }  
  38.   
  39.     @Resource  
  40.     public void setVoteLogDao(VoteLogDao voteLogDao) {  
  41.         this.voteLogDao = voteLogDao;  
  42.     }  
  43.   
  44.     @Override  
  45.     protected void beforeAddInput(Model model) {  
  46.     }  
  47.   
  48.     @Override  
  49.     protected void errorDeal(Model model) {  
  50.     }  
  51.   
  52.     @Override  
  53.     public String getJspFolder() {  
  54.         return null;  
  55.     }  
  56.   
  57.     /*** 
  58.      * @param model 
  59.      * @param conventionId 
  60.      * @param testBoyId 
  61.      * @param session 
  62.      * @param request 
  63.      * @param callback 
  64.      * @return :result:2--未登录;3--已经投票过 
  65.      * @throws IOException 
  66.      */  
  67.     @ResponseBody  
  68.     @RequestMapping(value = "/vote", produces = SystemHWUtil.RESPONSE_CONTENTTYPE_JSON_UTF)  
  69.     public String jsonVote(Model model, int conventionId, int testBoyId, HttpSession session,  
  70.                            HttpServletRequest request, String callback) throws IOException {  
  71.         User user2 = (User) session.getAttribute(Constant2.SESSION_KEY_LOGINED_USER);  
  72.         Map map = new HashMap();  
  73.         if (!AuthenticateUtil.isLogined(session)) {  
  74.             map.put(Constant2.LOGIN_RESULT_KEY, Constant2.MODIFY_PASS_RESULT_NOT_LOGINED_YET);//没有登录  
  75.             return HWJacksonUtils.getJsonP(map, callback);  
  76.         }  
  77.         VoteLog voteLogTmp = this.voteLogDao.get("user.id", user2.getId(), "convention.id", conventionId);  
  78.   
  79.   
  80.         if (voteLogTmp == null) {//说明还没有点赞  
  81.             Convention convention = conventionDao.get(conventionId);  
  82.             VoteLog voteLog = new VoteLog();  
  83.             voteLog.setConvention(convention);  
  84.             voteLog.setUser(user2);  
  85.             voteLog.setVoteTime(TimeHWUtil.getCurrentFormattedTime());  
  86.             this.voteLogDao.save(voteLog);  
  87.             int stars = convention.getStars();  
  88.             conventionDao.updateSpecail(conventionId, "stars", stars + 1);  
  89.             test2BoyDao.updateTime(testBoyId);  
  90. //          map.put("voteCount", voteCount);  
  91.   
  92.             map.put(Constant2.LOGIN_RESULT_KEY, Constant2.LOGIN_RESULT_SUCCESS);  
  93.         } else {  
  94.             //查询投票数  
  95.             /*Vote vote=this.voteDao.get("type", type, "houseBuilding.id", houseBuildingIdInt); 
  96.             map.put("voteCount", vote==null?0:vote.getVoteCount());*/  
  97.             map.put(Constant2.LOGIN_RESULT_KEY, 3);//已经投票过  
  98.         }  
  99.         return HWJacksonUtils.getJsonP(map, callback);  
  100.     }  
  101.   
  102.      
  103.   
  104.     public ConventionDao getConventionDao() {  
  105.         return conventionDao;  
  106.     }  
  107.   
  108.     @Resource  
  109.     public void setConventionDao(ConventionDao conventionDao) {  
  110.         this.conventionDao = conventionDao;  
  111.     }  
  112.   
  113.     public Test2BoyDao getTest2BoyDao() {  
  114.         return test2BoyDao;  
  115.     }  
  116.   
  117.     @Resource  
  118.     public void setTest2BoyDao(Test2BoyDao test2BoyDao) {  
  119.         this.test2BoyDao = test2BoyDao;  
  120.     }  
  121. }  

 

ajax调用投票接口:

Js代码   收藏代码
  1. var voteConvention= function (self,conventionId,testBoyId) {  
  2.     var options = {  
  3.         url: server_url + "/vote/vote?conventionId=" + conventionId +'&testBoyId='+testBoyId,  
  4.         type: "POST",  
  5.         dataType: 'json',  
  6.         success: function (json2) {  
  7.             if (json2.result==1) {  
  8.                 $(self).parent().text("已赞");  
  9.                 //alert("点赞成功");  
  10.             }else if (json2.result==3) {  
  11.                 alert("您已经点过赞")  
  12.             }  
  13.         },  
  14.         error: function (er) {  
  15.             console.log(er)  
  16.         }  
  17.     };  
  18.     $.ajax(options);  
  19. };  

 

界面如下:



 

 

查询时需要知道点赞的数量:

点赞的数量(总数)就是Convention的成员变量stars,每次点赞时都会更新

 

还需要判断当前用户是否已经点过赞:



 

 

 总结:

(1)点赞记录和用户是多对一的关系,即一个用户可以有多个点赞记录,但是一个点赞记录不可能属于多个用户;

(2)点赞的总记录存储在Convention中,而不是通过点赞记录查询到的,也就是说有两种方式获取一个帖子点了多少赞:

方式一:通过Convention中的stars;

方式二:查询点赞记录表

理论上,两种方式的结果是相同的.这里存在信息的冗余,冗余的目的是节约查询成本

 

数据表结构如下:



 

 

概要介绍:本门课程属于“Java分布式中间件大汇聚实战”系列课程,主要介绍了企业级项目中真实的应用场景的实现及主流的Java核心技术栈(Redis、RabbitMQ、Spring AOP、Redisson、ZooKeeper…)的实战等等。除此之外,还介绍了如何基于Redis设计并实战一款点赞系统(点赞、取消点赞、排行榜、用户中心、文章点赞用户列表…)可以说技术干货甚多,不仅可以巩固企业级应用系统的开发实战能力,相信在面试、跳槽涨薪方面也能带来相应的帮助!课程内容:传说中的金三银四、面试跳槽涨薪季已经来临,Debug特地为大家准备了一系列跟面试、跳槽、巩固核心技术栈相关的课程,本门课程属于第一季,其中的内容包括企业级项目中真实的应用场景实战、面试相关的技术点分享、主流的Java技术栈(Undertow、Redis、RabbitMQ、Spring AOP、Redisson、ZooKeeper…)实战等等。除此之外,我们还基于Redis设计并实战了一款点赞系统,可以说技术干货甚多。在课程的最后,Debug给大家整理了一份最新的面向BAT大厂招聘 ~ 2020年程序猿最新的Java面试题(附带目录和答案),希望对各位小伙伴的成长有所帮助!值得一提的是,本季课程实战的应用场景包括“日志记录”、“邮件发送”、“通告消息通知”、“短信验证码失效验证”、“会员到期自动提醒/到期前N天自动提醒”以及“点赞系统”的设计与实战,其大纲如下所示:其中,涉及到的技术栈包括Spring Boot2.0、Mybatis、Undertow、Redis、RabbitMQ、Redisson、Spring AOP、 Java8…下面罗列出本门课程重点介绍的价格应用案例以及业务场景的实现流程图!(1)基于Spring的消息驱动模型实现日志的异步记录:(2)基于消息中间件RabbitMQ的消息队列实现日志的异步记录:(3)基于缓存中间件Redis的订阅发布机制实现商户公告消息通知:(4)基于Redis的Key失效与定时任务实现实现短信验证码的过期失效验证:其他核心、典型的应用案例和业务场景的实战可以详细参考“课程目录”!除此之外,我们还基于缓存中间件Redis设计并实战实现了点赞系统中的点赞功能模块,下面罗列出其中涉及到的相关功能模块的实战流程图:其课程收益如下所示:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值