点赞功能的设计
每一次点赞,需要记录:
(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; } }
投票的控制器:
- package com.girltest.web.controller;
- import com.common.dict.Constant2;
- import com.common.util.SystemHWUtil;
- import com.girltest.dao.ConventionDao;
- import com.girltest.dao.Test2BoyDao;
- import com.girltest.dao.VoteLogDao;
- import com.girltest.entity.Convention;
- import com.girltest.entity.User;
- import com.girltest.entity.VoteLog;
- import com.io.hw.json.HWJacksonUtils;
- import com.time.util.TimeHWUtil;
- import oa.util.AuthenticateUtil;
- import oa.web.controller.base.BaseController;
- import org.springframework.stereotype.Controller;
- import org.springframework.ui.Model;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.ResponseBody;
- import javax.annotation.Resource;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpSession;
- import java.io.IOException;
- import java.util.HashMap;
- import java.util.Map;
- @Controller
- @RequestMapping("/vote")
- public class VoteController extends BaseController<VoteLog> {
- private VoteLogDao voteLogDao;
- private ConventionDao conventionDao;
- private Test2BoyDao test2BoyDao;
- public VoteLogDao getVoteLogDao() {
- return voteLogDao;
- }
- @Resource
- public void setVoteLogDao(VoteLogDao voteLogDao) {
- this.voteLogDao = voteLogDao;
- }
- @Override
- protected void beforeAddInput(Model model) {
- }
- @Override
- protected void errorDeal(Model model) {
- }
- @Override
- public String getJspFolder() {
- return null;
- }
- /***
- * @param model
- * @param conventionId
- * @param testBoyId
- * @param session
- * @param request
- * @param callback
- * @return :result:2--未登录;3--已经投票过
- * @throws IOException
- */
- @ResponseBody
- @RequestMapping(value = "/vote", produces = SystemHWUtil.RESPONSE_CONTENTTYPE_JSON_UTF)
- public String jsonVote(Model model, int conventionId, int testBoyId, HttpSession session,
- HttpServletRequest request, String callback) throws IOException {
- User user2 = (User) session.getAttribute(Constant2.SESSION_KEY_LOGINED_USER);
- Map map = new HashMap();
- if (!AuthenticateUtil.isLogined(session)) {
- map.put(Constant2.LOGIN_RESULT_KEY, Constant2.MODIFY_PASS_RESULT_NOT_LOGINED_YET);//没有登录
- return HWJacksonUtils.getJsonP(map, callback);
- }
- VoteLog voteLogTmp = this.voteLogDao.get("user.id", user2.getId(), "convention.id", conventionId);
- if (voteLogTmp == null) {//说明还没有点赞
- Convention convention = conventionDao.get(conventionId);
- VoteLog voteLog = new VoteLog();
- voteLog.setConvention(convention);
- voteLog.setUser(user2);
- voteLog.setVoteTime(TimeHWUtil.getCurrentFormattedTime());
- this.voteLogDao.save(voteLog);
- int stars = convention.getStars();
- conventionDao.updateSpecail(conventionId, "stars", stars + 1);
- test2BoyDao.updateTime(testBoyId);
- // map.put("voteCount", voteCount);
- map.put(Constant2.LOGIN_RESULT_KEY, Constant2.LOGIN_RESULT_SUCCESS);
- } else {
- //查询投票数
- /*Vote vote=this.voteDao.get("type", type, "houseBuilding.id", houseBuildingIdInt);
- map.put("voteCount", vote==null?0:vote.getVoteCount());*/
- map.put(Constant2.LOGIN_RESULT_KEY, 3);//已经投票过
- }
- return HWJacksonUtils.getJsonP(map, callback);
- }
- public ConventionDao getConventionDao() {
- return conventionDao;
- }
- @Resource
- public void setConventionDao(ConventionDao conventionDao) {
- this.conventionDao = conventionDao;
- }
- public Test2BoyDao getTest2BoyDao() {
- return test2BoyDao;
- }
- @Resource
- public void setTest2BoyDao(Test2BoyDao test2BoyDao) {
- this.test2BoyDao = test2BoyDao;
- }
- }
ajax调用投票接口:
- var voteConvention= function (self,conventionId,testBoyId) {
- var options = {
- url: server_url + "/vote/vote?conventionId=" + conventionId +'&testBoyId='+testBoyId,
- type: "POST",
- dataType: 'json',
- success: function (json2) {
- if (json2.result==1) {
- $(self).parent().text("已赞");
- //alert("点赞成功");
- }else if (json2.result==3) {
- alert("您已经点过赞")
- }
- },
- error: function (er) {
- console.log(er)
- }
- };
- $.ajax(options);
- };
界面如下:
查询时需要知道点赞的数量:
点赞的数量(总数)就是Convention的成员变量stars,每次点赞时都会更新
还需要判断当前用户是否已经点过赞:
总结:
(1)点赞记录和用户是多对一的关系,即一个用户可以有多个点赞记录,但是一个点赞记录不可能属于多个用户;
(2)点赞的总记录存储在Convention中,而不是通过点赞记录查询到的,也就是说有两种方式获取一个帖子点了多少赞:
方式一:通过Convention中的stars;
方式二:查询点赞记录表
理论上,两种方式的结果是相同的.这里存在信息的冗余,冗余的目的是节约查询成本
数据表结构如下: