Spring FrameWork에서 좋아요 기능을 간단하게 구현하는 방법입니다.
- 참고사항 (필독!)
- 개발환경 : Mac
- DB : MySQL
- 게시글번호 & 회원번호 : long
- 테이블 이름 : exhibition_table(게시판) & member_table(회원)
- mybatis-config.xml : HeartDTO를 hdto로 선언
- 좋아요를 누를 시 heart가 1로 변경, 취소 시 저장된 데이터 삭제하는 방식
- 좋아요 갯수 세는 것 제외 (좋아요 기능만 정리)
- 코드는 본인거에 맞게 수정해서 쓰세요~
create table exhibition_table (
e_number bigint auto_increment,
e_title varchar(50) not null,
e_writer varchar(20) not null,
e_contents varchar(2000) not null,
e_hits int default 0,
e_date datetime,
e_filename varchar(100),
e_email varchar(100),
e_count bigint,
constraint primary key(e_number)
);
create table member_table (
m_number bigint auto_increment,
m_id varchar(20) not null unique,
m_pw varchar(16) not null,
m_name varchar(20) not null,
m_phone varchar(20) not null,
m_filename varchar(100),
constraint primary key(m_number)
);
create table heart_table (
-- pk값으로 쓸 컬럼
h_number bigint auto_increment,
-- 게시글 번호
e_number bigint,
-- 회원 번호
m_number bigint,
-- 좋아요
heart int,
constraint primary key(h_number)
);
@Data
public class HeartDTO {
// pk값으로 쓸 번호
private long h_number;
// 게시글 번호
private long e_number;
// 회원 번호
private long m_number;
// 좋아요
private int heart;
}
detail.jsp(상세조회)를 가기전에 회원이 해당 게시글에 좋아요를 한게 있는지 체크하는 부분.
@RequestMapping(value="detail",method=RequestMethod.GET)
public String detail(@RequestParam("e_number") long e_number, Model model, @RequestParam(value="page", required=false, defaultValue="1")int page, @RequestParam("m_number") long m_number) {
// 기존 detail부분
ExhibitionDTO exhibition = es.detail(e_number);
model.addAttribute("exhibition",exhibition);
model.addAttribute("page", page);
// 아래부터 좋아요 기능 시 추가되는 부분
HeartDTO heart = new HeartDTO();
// 좋아요가 되있는지 찾기위해 게시글번호와 회원번호를 보냄.
heart = es.findHeart(e_number, m_number);
// 찾은 정보를 heart로 담아서 보냄
model.addAttribute("heart",heart);
return "exhibition/detail";
}
public HeartDTO findHeart(long e_number, long m_number) {
// 2개의 parameter를 보내기 위해 Map 선언 및 Map에 데이터 삽입
Map<String, Long> number = new HashMap<String, Long>();
number.put("e_number", e_number);
number.put("m_number", m_number);
return er.findHeart(number);
}
public HeartDTO findHeart(Map<String, Long> number) {
return sql.selectOne("Exhibition.findHeart",number);
}
<select id="findHeart" parameterType="java.util.HashMap" resultType="hdto">
select * from heart_table where e_number=#{e_number} and m_number=#{m_number}
</select>
위 코드가 전부 끝나면 detail.jsp가 출력됨.
회원번호는 로그인시 session에 loginNumber로 담겨져 있음.
${sessionScope.loginNumber}부분은 본인걸로 변경
// 좋아요 버튼을 생성하는 코드
// 좋아요 이미지는 부트스트랩 아이콘의 heart.svg, heart-fill.svg 저장해서 사용
// heart : 좋아요O, heart-fill : 좋아요X
// 경로는 resouces폴더의 icon폴더안에 저장
// 이미지 경로는 맥 기준이므로 윈도우사용자는 윈도우에 맞게 변경할 것
<div>
<a class="text-dark heart" style="text-decoration-line: none;">
<img id="heart" src="/resources/icon/heart.svg">
좋아요
</a>
</div>
// </body> 밑부분에 script 작성
// AJAX를 사용하므로 jQuery 사용 선언 (버젼은 본인걸로 알아서 변경)
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script>
$(document).ready(function () {
// 좋아요가 있는지 확인한 값을 heartval에 저장
var heartval = ${heart.heart}
// heartval이 1이면 좋아요가 이미 되있는것이므로 heart-fill.svg를 출력하는 코드
if(heartval>0) {
console.log(heartval);
$("#heart").prop("src", "/resources/icon/heart-fill.svg");
$(".heart").prop('name',heartval)
}
else {
console.log(heartval);
$("#heart").prop("src", "/resources/icon/heart.svg");
$(".heart").prop('name',heartval)
}
// 좋아요 버튼을 클릭 시 실행되는 코드
$(".heart").on("click", function () {
var that = $(".heart");
$.ajax({
url :'/exhibition/heart',
type :'POST',
data : {'e_number':${exhibition.e_number}, 'm_number':${sessionScope.loginNumber}},
success : function(data){
that.prop('name',data);
if(data==1) {
$('#heart').prop("src","/resources/icon/heart-fill.svg");
} else {
$('#heart').prop("src","/resources/icon/heart.svg");
}
}
});
});
});
</script>
AJAX에서 요청한 정보를 받아서 처리후 보내는 메서드
@RequestMapping(value="heart",method=RequestMethod.POST)
public @ResponseBody int heart(@ModelAttribute HeartDTO heart) {
int result = es.insertHeart(heart);
return result;
}
public int insertHeart(HeartDTO heart) {
// 좋아요가 DB에 저장이 되는것이 없으면 0이 그대로 리턴으로 넘어감
int result = 0;
// 좋아요가 이미 있는지 확인하는 코드
HeartDTO find = er.findHeart(heart);
// find가 null이면 좋아요가 없는 상태이므로 정보 저장
// find가 null이 아니면 좋아요가 있는 상태이므로 정보 삭제
if(find==null) {
// insert의 리턴값은 DB에 성공적으로 insert된 갯수를 보내므로 result가 1이 됨
result = er.insertHeart(heart);
} else {
er.deleteHeart(heart);
}
// 0 or 1이 담겨져서 @Controller에 보냄.
return result;
}
// 좋아요가 DB에 있는지 확인
public HeartDTO findHeart(HeartDTO heart) {
return sql.selectOne("Exhibition.findHeart",heart);
}
// 좋아요 정보(heart_table에 게시글 번호, 회원 번호) 저장
public int insertHeart(HeartDTO heart) {
return sql.insert("Exhibition.insertHeart", heart);
}
// 좋아요 삭제
public void deleteHeart(HeartDTO heart) {
sql.delete("Exhibition.deleteHeart",heart);
}
// 좋아요 확인
<select id="findHeart" parameterType="hdto" resultType="hdto">
select * from heart_table where e_number=#{e_number} and m_number=#{m_number}
</select>
// 좋아요 저장
<insert id="insertHeart" parameterType="hdto">
insert into heart_table(e_number, m_number, heart)
values(#{e_number}, #{m_number}, 1)
</insert>
// 좋아요 삭제
<delete id="deleteHeart" parameterType="hdto">
delete from heart_table where e_number=#{e_number} and m_number=#{m_number}
</delete>
마치며
좋아요기능을 정말 간단하게 구현하는 코드이므로 참고용으로 봐주시면 감사하겠습니다 :D