Programming language/Javascript,jQuery

[JQuery+Ajax]좋아요 기능 구현 - (1)

  • -
반응형

관련 소스는 https://github.com/eeesnghyun/LikeFunction에서 확인하실 수 있습니다.




학부시절 취업성공패키지로 한 학기를 대신한 국비지원교육을 받을 수 있었다.

교육당시 재미삼아 개인프로젝트를 진행했었는데 그 때 만들었던 좋아요 기능을 기록에 남기려고 한다.

이 기능을 구현하기 위해 3일을 넘게 애먹었던 것 같다...


내가 생각한 로직은 아래와 같다.

1)유저가 게시판을 조회 한다.

2)좋아요 버튼을 클릭 시 로그인 여부를 파악한다.

3)회원 여부를 로그인을 통해 파악한다.(회원이라면 통과, 비회원이라면 회원가입)

4)좋아요 클릭시 +1, 취소시 0


이 때, DB(좋아요 테이블을 따로 제작)에는 좋아요 번호가 PK로 등록되어 있으며 

게시판 번호와 회원번호는 FK 그리고 좋아요 체크값(DEFAULT 0)을 갖는다.

(좋아요 이벤트 발생시 like_cnt를 올려줘야 하기 때문에 게시판 테이블에는 기본적으로 like_cnt가 있어야 한다)


1
2
3
4
5
6
7
8
CREATE TABLE liketo(
    likeno                      NUMBER(5)    NOT NULL PRIMARY KEY
    boardno                   NUMBER(5)    NOT NULL,    
    mno                        NUMBER(6)    NOT NULL,
    like_check                 NUMBER(5)    DEFAULT 0 NULL,
    FOREIGN KEY (mno) REFERENCES member (mno),
    FOREIGN KEY (boardno) REFERENCES board (boardno)
);
cs



EX)

A라는 게시글이 있을 때 'SH'회원이 좋아요를 한다고 하면

좋아요 체크값을 이용해 A라는 게시글에 'SH'회원의 좋아요 체크값은 +1이 된다.

만약 다시 좋아요를 누른다면 좋아요의 중복을 막기 위해 회원의 좋아요 체크값을 비교한다.

체크 값이 1일 경우 좋아요 취소 로직을 타게 되고 다시 0이 된다.


프로그램 설계는 스프링 MVC2모델로 했으며, Mybatis를 연동해 DB를 연결했다.

jsp(ajax통신)->Cont->Proc->DAO->MyBatis->DB(Oracle)

요런 구조??


아래는 좋아요를 체크하는 쿼리문

좋아요 버튼 클릭 이벤트 시에 실행된다. 


1
2
3
4
5
6
7
8
9
10
11
 <update id="like_check" parameterType="HashMap">
    UPDATE liketo
    SET like_check = like_check + 1 
    WHERE mno=#{mno} AND boardno=#{boardno}
  </update>
  
  <update id="like_check_cancel" parameterType="HashMap">
    UPDATE liketo
    SET like_check = 0
    WHERE mno=#{mno} AND boardno=#{boardno}
  </update>
cs


이 프로젝트의 프론트단은 거의 대부분 Ajax+Modal창을 이용해서 만들었다.

이벤트 발생 시 간단하게 이미지변경과 메세지를 띄어주는 정도만 구현해 보았다.


먼저 좋아요 이미지 버튼 부분.

초기 이미지는 빈 하트로 설정, 좋아요 클릭시 변경된다.

비회원일 때는 아래와 같이 JSTL을 사용하여 다른 이벤트를 타도록 만들었다.


1
2
3
4
5
6
7
8
<c:choose>
  <c:when test="${mno ne null}">
    <a href='javascript: like_func();'><img src='./images/dislike.png' id='like_img'></a>
  </c:when>
  <c:otherwise>
    <a href='javascript: login_need();'><img src='./images/dislike.png'></a>
  </c:otherwise>
</c:choose>
cs


      ☞


하지만 초기 이미지가 계속 빈 하트라면 이미 좋아요를 한 회원에게도 똑같이 나타나지 않을까?

이 문제는 게시글 조회 시 회원의 좋아요 여부에 따라 그림이 다르도록 구현하였다. 


아래 코드는 좋아요 클릭 시 function을 타고 ajax로 데이터를 넘긴 부분.

ajax로게시판 번호를 넘겼고 회원 번호는 java단에서 세션을 통해 받아온다.


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
/* 좋아요 */
function like_func(){
  var frm_read = $('#frm_read');
  var boardno = $('#boardno', frm_read).val();
  //var mno = $('#mno', frm_read).val();
  //console.log("boardno, mno : " + boardno +","+ mno);
  
  $.ajax({
    url: "../liketo/like.do",
    type: "GET",
    cache: false,
    dataType: "json",
    data: 'boardno=' +boardno,
    success: function(data) {
      var msg = '';
      var like_img = '';
      msg += data.msg;
      alert(msg);
      
      if(data.like_check == 0){
        like_img = "./images/dislike.png";
      } else {
        like_img = "./images/like.png";
      }      
      $('#like_img', frm_read).attr('src', like_img);
      $('#like_cnt').html(data.like_cnt);
      $('#like_check').html(data.like_check);
    },
    error: function(request, status, error){
      alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
    }
  });
}
cs


앞서 말했듯 나는 게시판 번호와 회원번호를 이용해 그 회원의 좋아요 여부를 판단했다.

두 값을 보내기 위해 HashMap을 이용했고 liketoProc.read(hashMap)에는 회원의 좋아요 정보가 담겨있다. 

LiketoVO라는 객체 안에 회원의 좋아요 정보를 담고, 체크값을 꺼내 비교를 한다. 

이 회원이 좋아요를 했는지, 안했는지.

그러면 일단 기능은 구현이 된다.

하지만 문제가 발생했었는데.. 이 부분에 대해서는 다음 장에서 다뤄야겠다.


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
 @ResponseBody
  @RequestMapping(value="/liketo/like.do", method=RequestMethod.GET, produces="text/plain;charset=UTF-8")
  public String like(int boardno, HttpSession session){
    //System.out.println("--> like() created");
    int mno = (Integer)session.getAttribute("mno");
    JSONObject obj = new JSONObject();
 
    ArrayList<String> msgs = new ArrayList<String>();
    HashMap <String, Object> hashMap = new HashMap<String, Object>();
    hashMap.put("boardno", boardno);
    hashMap.put("mno", mno);
    LiketoVO liketoVO = liketoProc.read(hashMap);
    
    BoardVO boardVO = boardProc.read(boardno);
    int like_cnt = boardVO.getLike_cnt();     //게시판의 좋아요 카운트
    int like_check = 0;
    like_check = liketoVO.getLike_check();    //좋아요 체크 값
    
    if(liketoProc.countbyLike(hashMap)==0){
      liketoProc.create(hashMap);
    }
      
    if(like_check == 0) {
      msgs.add("좋아요!");
      liketoProc.like_check(hashMap);
      like_check++;
      like_cnt++;
      boardProc.like_cnt_up(boardno);   //좋아요 갯수 증가
    } else {
      msgs.add("좋아요 취소");
      liketoProc.like_check_cancel(hashMap);
      like_check--;
      like_cnt--
      boardProc.like_cnt_down(boardno);   //좋아요 갯수 감소
    }
    obj.put("boardno", liketoVO.getBoardno());
    obj.put("like_check", like_check);
    obj.put("like_cnt", like_cnt);
    obj.put("msg", msgs);
    
    return obj.toJSONString();
  }
cs


반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.