좋아요를 누르기 위해서 필요한 정보가 들어있는 table 생성
CREATE TABLE snslike(
bno NUMBER(10,0) NOT NULL,
userID VARCHAR2(50) NOT NULL,
lno NUMBER primary key
);
CREATE SEQUENCE snslike_seq
START WITH 1
INCREMENT BY 1
MAXVALUE 10000
NOCYCLE
NOCACHE;
정보를 저장할 수 있는 VO객체 생성
package com.spring.myweb.command;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class SnsLikeVO {
/*
CREATE TABLE snslike(
bno NUMBER(10,0) NOT NULL,
userID VARCHAR2(50) NOT NULL,
lno NUMBER primary key
);
CREATE SEQUENCE snslike_seq
START WITH 1
INCREMENT BY 1
MAXVALUE 10000
NOCYCLE
NOCACHE;
*/
private int bno;
private String userId;
private int lno;
}
좋아요 기능을 구현하기 위해 해당 정보를 DB에서 가지고 올 수 있는 SQL문 작성
<!-- 좋아요 검색 -->
<select id="searchLike" resultType="int">
SELECT COUNT(*) FROM snslike
WHERE bno = #{bno} AND userId = #{userId}
</select>
<!-- 좋아요 등록 -->
<insert id="createLike">
INSERT INTO snslike(bno, userId, lno)
VALUES(#{bno}, #{userId}, snslike_seq.NEXTVAL)
</insert>
<!-- 좋아요 삭제 -->
<delete id="deleteLike">
DELETE FROM snslike
WHERE bno = #{bno} AND userID = #{userId}
</delete>
Code
$('#contentDiv').on('click', '#likeBtn', function(event) {
// 좋아요 버튼은 반복문을 돌면서 생기기 때문에 실제 존재하는 contetnDiv에서 이벤트 전파 방식 사용
event.preventDefault();
console.log('좋아요 버튼 클릭');
if (event.target.matches('img')){
$('#likeBtn').click();
return;
}
const bno = $(this).attr('href');
// href에 묻혀져 있는 게시글 번호 가져옴
const id = '${login.userId}';
// 현재 로그인 중인 아이디
// session에서가져옴
if (id === ''){
alert('로그인한 사용자만 가능합니다.');
return;
}
$.ajax({
type :'post',
url : '<c:url value="/snsBoard/like" />',
// url에 묻혀서 보낼 수 있음
contentType : 'application/json',
data : JSON.stringify({
'bno' : bno,
'userId' : id
}),
success : function(result){
if (result === 'like'){
// vanilla JS
// 좋아요를 눌렀다면 스타일 변경
event.target.firstChild.setAttribute('src', '${pageContext.request.contextPath}/img/like2.png');
// 이벤트가 발생한 곳의 html 삽입
event.target.style.color = 'blue';
// 이벤트가 발생한 곳의 글자색을 바꿈
const $cnt = event.target.parentNode.previousElementSibling.children[1];
// 현재 이벤트가 발생한 곳의 부모노드의 형제 노드의 두번째 자식노드를 지목
// console.log($cnt);
// 값을 가져오는 것을 확인
$cnt.textContent = Number($cnt.textContent) + 1;
// 기존의 html의 값을 숫자로 변환해서 하나 더 올려줌
}
else{
// vanilla JS
event.target.firstChild.setAttribute('src', '${pageContext.request.contextPath}/img/like1.png');
event.target.style.color = 'black';
// 이벤트가 발생항 곳의 html을 삽입하고 글자색을 변경
const $cnt = event.target.parentNode.previousElementSibling.children[1];
// 현재 이벤트가 발생한 곳의 부모노드의 형제 노드의 두번째 자식노드를 지목
// console.log($cnt);
// 값을 가져오는 것을 확인
$cnt.textContent = Number($cnt.textContent) -1;
// 기존의 html의 값을 숫자로 변환해서 하나 더 빼
}
},
error : function(){
alert('좋아요 기능에서 오류가 발생했습니다.');
}
}); // end ajax
}); // 좋아요 기능 끄읏~
각 게시물의 좋아요 정보를 저장
let str ='';
let page = 1;
getListLike(true).done(getList);
// getListLike함수에 promise를 사용해서 순서를 지목하고 해당 함수에 done을 작성하게 되면
// getListLike()함수를 먼저 실행하고 getLis함수를 실행하라는 순서를 지목해줌
// 게시판에 들어온 회원의 종아요 게시물 목록을 받아오는 함수
function getListLike(isReset){
let deferred = $.Deferred();
// jquery에서 제공하는 Deferred함수이며 함수들의 실행순서를 정할 수 있게 해줌
console.log('먼저 실행되어야 합니다.');
const userId = '${login.userId}';
if(userId !== ''){
// 로그인을 한 사용자라면
$.ajax({
type : 'post',
url : '<c:url value="/snsBoard/listLike" />',
data : userId,
contentType:'application/json',
success : function(result){
console.log('result : ' + result);
// 게시물 번호들
if (isReset){
deferred.resolve(result, page, true);
}
else {
deferred.resolve(result, page, false);
}
}
}); // end ajax
}
else{
if (isReset){
deferred.resolve(null, page, true);
}
else {
deferred.resolve(null, page, false);
}
}
return deferred.promise();
// 순서를 지목하기 위해 promise 사용
비동기 통신은 실행되는 순서가 정해져 있지 않기 때문에 문제가 발생할 수 있음 그러므로 Deferred함수의 Promise라는 함수를 통해 순서를 부여
Deferred
제약 조건 추가
외래키(FK)를 참조할 때 참조하는 데이터가 삭제되는 경우 참조하고 있는 데이터도 함께 삭제 진행 (CASCADE)
ALTER TABLE snslike ADD FOREIGN KEY(bno)
REFERENCES snsboard(bno)
ON DELETE CASCADE;
-- foreign key로 참조하는 데이터가 사라지면 참조를 하고 있는 데이터도 함께 삭제
ALTER TABLE snslike ADD FOREIGN KEY(userId)
REFERENCES USERS(userid)
ON DELETE CASCADE;
Code
// 좋아요 버튼 클릭 처리
@PostMapping("/like")
@ResponseBody
public String likeConfirm(@RequestBody SnsLikeVO like) {
// JSON으로 값이 들어오기 때문에 @RequestBody와 커맨드 객체를 사용해서 JSON 타입을 객첼 변경
System.out.println("/snsBoard/like : POST ");
System.out.println("좋아요 기능 값을 가져오는지 확인 : " + like);
// 좋아요 버튼은 버튼이 하나임으로 버튼을 클릭 유무에 따라 좋아요 선택 및 취소를 뜻
int result = service.searchLike(like);
// 좋아요를 눌렀다면 1이 오고 좋아요를 누르지 않았다면 0이 옴
if(result == 0) {
// 좋아요를 누르지 않았다면 해당 정보를 db에 저장
service.createLike(like);
return "like";
}
else {
// 좋아요를 눌렀으므로 db에서 해당 값 삭제
service.deleteLike(like);
return "delete";
}
}
// 회원이 글 목록 진입시 좋아요 게시물 수 체크
@PostMapping("/listLike")
@ResponseBody
public List<Integer> listLike(@RequestBody String userId){
System.out.println("/snsBoard/listLike : POST");
System.out.println("좋아요 게시물 체크 : " + userId);
List<Integer> likeList = service.listLike(userId);
System.out.println(likeList);
return likeList;
}