일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- REST
- paginationInfo
- SpringFramework
- 비동기
- Boot
- 외부접속
- CRUD
- egov
- DAO
- modal #alert #sweetalert #sweetAlert #모달
- deferred
- 우리마
- Spring
- Controller
- 대댓글
- Today
- Total
우리마의 웹 개발
[Spring]게시판 글 상세보기에서 '좋아요' 처리 로직 정리 본문
Spring환경에서 게시판으로 개발 연습을 하면서 게시글에 대해서 해당 글의 '좋아요' 처리에 대한 개인적인 로직을 정리하고자 한다. 지극히 주관적인 로직과 코딩이라서 상당히 하드 할 수 있다.
지적사항, 더좋은 방법 등 댓글 환영
개발 환경 | |
Spring Framework | 5.2.3 |
Tomcat | 8.0 |
DB | MySql8 , MyBatis3.5 |
Browser | Chrome |
IDE | STS 3.9.11 |
DB '좋아요' 테이블 구조
bbsidx와 useridx는 각각 게시글 테이블과 사용자 테이블의 일련번호를 외래 키로 사용하고 있다.
게시글을 본 사용자에 대해서 '좋아요'를 처리하기 위함이다.
게시글 상세보기 페이지 최초 접속시 처리 프로세스
'좋아요'버튼 (하트) 눌렀을때 처리 프로세스
게시글 상세보기 페이지 접속 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
/* Controller */
//게시글 상세보기 detail
@RequestMapping("/communityDetail")
public String communityDetail(@RequestParam int idx, Model model,HttpServletRequest request,HttpServletResponse response, HttpSession session){
logger.info("request: /communityDetail");
Map<String,Object> resultMap = null;
Map<String,Object> idxMap = new HashMap<>();
int bbsidx = idx;
int useridx = 0;
/* 생략 */
try {
Map<String,Object> userInfo = (Map<String, Object>) session.getAttribute("userInfo");
useridx = Integer.parseInt(userInfo.get("idx").toString());
/* 생략 */
resultMap = service.communityDetail(bbsidx); // 게시판 상세정보 가져옴
idxMap.put("bbsidx", bbsidx);
idxMap.put("useridx", useridx);
Map<String,Object> likecheckMap = service.likecheck(idxMap);
//like 테이블 에서 사용자가 해당 게시글에 대해서 좋아요를 눌렀는지 확인
if(likecheckMap == null) {
//사용자가 좋아요를 한번도 누른적이 없으면 //like테이블에 데이터가 없으므로 null반환 model.addAttribute("likecheck",0);
}
else {
model.addAttribute("likecheck",likecheckMap.get("likecheck"));
}
model.addAttribute("likecnt",resultMap.get("likecnt"));
model.addAttribute("bbsidx",bbsidx); model.addAttribute("useridx",useridx); /* 생략 */
} catch (Exception e) {
logger.debug(e.getMessage());
}
return "communityDetail";
}
/* SQL.xml */
<select id="communityDetail" resultType="map">
SELECT
//생략
, bbs.likecnt as likecnt
//생략
from
training_bbs bbs
where 1=1
and bbs.idx = #{idx}
</select>
<!-- 좋아요 눌렀는지 여부 확인 -->
<select id="likecheck" resultType="map">
select likecheck
from training_like
where bbsidx=#{bbsidx}
and useridx=#{useridx}
</select>
/* communityDetail.jsp */
<c:choose>
<c:when test="${likecheck eq '0' or empty likecheck}"> <!-- likecheck가0이면 빈하트-->
<img src="/home/img/ico_like_before.png"
id="btn_like" align="left" style="cursor:pointer; width: 20px;">
</c:when>
<c:otherwise> <!-- likecheck가1이면 빨간 하트-->
<img src="/home/img/ico_like_after.png"
id="btn_like" align="left" style="cursor:pointer; width: 20px;">
</c:otherwise>
</c:choose>
<dd id="likecnt" style="margin-left:5px;">${likecnt}</dd>
|
cs |
|
|
communityDetail이 호출되었을 때 먼저 Controller에서 접속 중인 사용자에 대한 정보를 session에 등록된 정보 즉, userInfo에 있는 정보에서 사용자의 일련번호 (useridx)를 가져오고 communityDetail에 호출될때 파라미터로 해당 게시글의 일련번호(bbsidx)를 받는다. 이 두가지 값을 이용해서 해당 게시글에 사용자가 '좋아요'를 누른적있는지 없는지 확인한다.( 21번줄) 한번도 누른 적이 없으면 like테이블 조회 결과가 없으므로 null값이 들어갈 것이기 때문에 model로 jsp에 넘길 때 0을 담고(jsp에서 빈 하트 출력) 한 번이라도 누른 적이 있으면 like테이블의 likecheck 칼럼 값을 model에 담아 jsp로 넘긴다.
게시글의 좋아요 개수(likecnt) 값은 게시글 테이블에 값이 있다.
'좋아요'버튼(하트) 눌렀을때 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
/* JSP SCRIPT */
var bbsidx = ${bbsidx}; var useridx = ${useridx};
var btn_like = document.getElementById("btn_like");
btn_like.onclick = function(){ changeHeart(); }
/* 좋아요 버튼 눌렀을떄 */
function changeHeart(){
$.ajax({
type : "POST",
url : "/clickLike",
dataType : "json",
data : "bbsidx="+bbsidx+"&useridx="+useridx,
error : function(){
Rnd.alert("통신 에러","error","확인",function(){});
},
success : function(jdata) {
if(jdata.resultCode == -1){
Rnd.alert("좋아요 오류","error","확인",function(){});
}
else{
if(jdata.likecheck == 1){
$("#btn_like").attr("src","/home/img/ico_like_after.png");
$("#likecnt").empty();
$("#likecnt").append(jdata.likecnt);
}
else if (jdata.likecheck == 0){
$("#btn_like").attr("src","/home/img/ico_like_before.png");
$("#likecnt").empty();
$("#likecnt").append(jdata.likecnt);
}
}
}
});
}
/* Controller */
//좋아요 눌렀을때
@RequestMapping("/clickLike")
@ResponseBody
public Map<String,Object> clickLike(@RequestParam Map<String,Object> commandMap){
logger.info("request: /clickLike");
int resultCode = 1;
int likecheck = 1;
Map<String,Object> map = new HashMap<>();
Map<String,Object> likecntMap = new HashMap<>();
Map<String,Object> resultMap = new HashMap<>();
try {
map = service.likecheck(commandMap);
if(map == null) {
//처음 좋아요 누른것 likecheck=1, 좋아요 빨간색이 되야됨
service.insertLikeBtn(commandMap); //좋아요 테이블 인서트
service.updateLikeCntPlus(commandMap); //bbs 테이블 업데이트 +1
resultCode = 1;
}
else if(Integer.parseInt(map.get("likecheck").toString()) == 0) {
//좋아요 처음은 아니고 취소했다가 다시 눌렀을때 likecheck=1, 좋아요 빨간색 되야됨
commandMap.put("likecheck",likecheck);
service.updateLikeCheck(commandMap); //좋아요 테이블 업데이트
service.updateLikeCntPlus(commandMap); // bbs테이블 +1
resultCode = 1;
}
else {
//좋아요 취소한거 likecheck=0, 빈하트 되야됨
likecheck = 0;
commandMap.put("likecheck", likecheck);
service.updateLikeCheck(commandMap);
service.updateLikeCntMinus(commandMap);
resultCode = 0;
}
resultMap = service.getLikeCnt(commandMap);
// 해당 게시글 테이블의 likecnt칼럼 update가 끝난후 likecnt값 가져옴
resultMap.put("likecheck", likecheck);
} catch (Exception e) {
logger.debug(e.getMessage());
resultCode = -1;
}
resultMap.put("resultCode", resultCode);
//resultCode가 1이면 빨간하트 0이면 빈하트
return resultMap;
}
|
cs |
communityDetail.jsp 에서 script로 하트 버튼 이벤트를 등록하고 ajax를 통해 Controller로 bbsidx와 useridx를 파라미터로 넘겨준다. 이에 따라서 resultCode 값을 통해 '좋아요'를 눌렀는지 '좋아요 취소'를 했는지 확인할 수 있고, 빈 하트 또는 빨간 하트를 출력한다.
Controller에서 각각의 경우에 따라서 Service를 태우고 resultCode 값을 정한다 위에 있는 FlowChart와 주석 설명을 참조 바란다.
화면
처음에 로직을 생각할때 사용자가 해당 글에 대해서 '좋아요'를 누른 적 있는지 없는지, '좋아요'를 누른 적은 있는데 취소를 한 것인지 '좋아요'누른 상태 인지 등등 이런 경우들을 어떻게 구별하는지 고민을 많이 했는데 필자가 좀 어렵게 생각한 면도 있는 거 같고 지금 와서 봐도 상당히 하드코딩 느낌이 난다...
댓글로 더좋은 방법, 지적 환영합니다..
즐겁지 않은 즐거운 코딩 하세요.
'WEB > Spring' 카테고리의 다른 글
[eGovFramework]하나의 프로젝트에서 2개의 DB 사용 하기(Postgresql, Tibero DB) (4) | 2021.01.08 |
---|---|
[Spring]파일 업로드의 구현(1개의 파일) (1) | 2020.12.04 |
[Spring]페이징 처리 EgovFramework Paginationinfo 사용하기( JSP, Controller) (3) | 2020.07.21 |
[Spring]페이징 처리 EgovFramework Paginationinfo 사용하기( 설정) (3) | 2020.07.21 |
[Spring]학생들의 성적에 대한 CRUD기능 구현(데이터베이스 없이 DAO의 List로 DB대용) (2) | 2020.02.17 |