点赞功能的设计
每一次点赞,需要记录:
(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;
方式二:查询点赞记录表
理论上,两种方式的结果是相同的.这里存在信息的冗余,冗余的目的是节约查询成本
数据表结构如下: