느림보 개발
5. SpringMVC - 찜하기 본문
- 전체 흐름
1. 제품 상세 페이지에 접속시, 데이터베이스에서 사용자가 해당 상품에 찜하기 누렀는지의 여부를 가져와서 화면에 결과를 뿌려준다.
2. 찜하기를 누르면 Ajax 통신을 통해 데이터베이스에서 찜 여부를 체크하고 찜반영/취소를 데이터베이스에 반영 한뒤, 정수형으로 결과를 리턴하여 로직에 맞는 기능 수행
Controller
- 제품 상세페이지 호출시 찜 여부를 확인해 출력해야한다. 해당 페이지의 제품번호와 사용자 아이디를 likeVO에 저장해준 뒤, 객체의 변수를 가지고 brinkLike(lvo) 메서드 실행 → DB에서 일치하는 데이터가 있는지 확인 한 뒤 리턴 타입 LikeVO에 담아 반환한다.
- DB에서 일치하는 결과가 있다면 객체안에 내용이 있을 것이고, DB에서 일치하는 결과가 없다면 객체가 null이 된다.
- like == null 일 경우, LikeVO 인스턴스를 새로 생성하여 like에 저장시켜주고 찜여부에 0을 세팅해준다.
- like != null일 경우, 결과 받은대로 그대로 model 객체에 담아 JSP 딴으로 보낸다.
// 상품 상세 페이지 - 이동(GET)
@RequestMapping(value = "/productDetail", method = RequestMethod.GET)
public String productDetail(@RequestParam("prod_num") int prod_num, DealVO vo,Model model, HttpSession session) throws Exception {
... 생략 ...
LikeVO lvo = new LikeVO();
lvo.setProd_num(prod_num);
lvo.setBuyer_id(user_id);
LikeVO like = service.bringLike(lvo);
if(like != null) {
}else {
like = new LikeVO();
like.setCheck(0);
}
model.addAttribute("result",like);
... 생략 ...
return "/product/shopDetails";
}
Service, Impl / DAO, Impl / mapper
//상세페이지 좋아요
public LikeVO bringLike(LikeVO lvo) throws Exception;
//상세페이지 좋아요
@Override
public LikeVO bringLike(LikeVO lvo) throws Exception {
return dao.bringLike(lvo);
}
//상세페이지 좋아요
public LikeVO bringLike(LikeVO lvo) throws Exception;
//상세페이지 좋아요
@Override
public LikeVO bringLike(LikeVO lvo) throws Exception {
return sqlSession.selectOne(NAMESPACE + ".bringLike", lvo);
}
<!-- 상세페이지 좋아요 -->
<select id="bringLike" resultType="LikeVO">
select `check` from mfg_like where prod_num=${prod_num} and buyer_id=#{buyer_id}
</select>
제품 상세 페이지 - jsp
- 컨트롤러로부터 전달된 result가 null이 아닐 경우 result 안의 check는 0 또는 1이 되는데 0일 경우엔 찜하지 않은 상태로 빈 하트, 1일 경우엔 찜한 상태로 찬 하트 출력하도록 한다.
<c:if test="${result != null}">
<a class="like">
<c:if test="${result.check == 0}">
<img id="like" class="l1"
src="${pageContext.request.contextPath }/resources/img/core-img/heart.svg">
</c:if>
<c:if test="${result.check == 1}">
<img id="like" class="l1"
src="${pageContext.request.contextPath }/resources/img/core-img/heart-fill.svg">
</c:if>
</a>
</c:if>
- Ajax 통신 방식으로 제품번호와 사용자아이디의 값을 가져가 /product/like를 호출하면 해당 컨트롤러로 가게 된다.
- 컨트롤러로부터 받은 값이 1일 경우 = 찜이 완료된 상태이므로 알림창과 꽉찬하트로 이미지 변경
- 컨트롤러로부터 받은 값이 -1일 경우 = 비회원이므로 알림창 출력
- 컨트롤러로부터 받은 값이 그외일 경우 = 찜이 취소된 상태이므로 알림창과 빈하트로 이미지 변경
$(document).ready(function() {
$(".like").on("click", function(){
$.ajax({
url : "/product/like",
type: 'GET',
data: {'prod_num':'${deal.product.prod_num}', 'buyer_id':'${user_id}'},
success:function(data){
if(data==1){
like2 = true;
alert("상품 찜 하셨습니다.");
$('#like').attr("src","${pageContext.request.contextPath }/resources/img/core-img/heart-fill.svg");
var result = confirm('찜목록으로 이동하시겠습니까?');
if (result) {
//yes
//찜 리스트 페이지 생성 후 -> 찜리스트 페이지 이동으로 변경
location.href='/mypage/likeListAll ';
}
}
else if(data == -1){
alert("로그인이 필요한 서비스입니다. ");
}
else {
like2 =false;
alert("상품 찜 취소하셨습니다. ");
$('#like').attr("src","${pageContext.request.contextPath }/resources/img/core-img/heart.svg");
}
},
error:function(error){
console.log(error);
}
});
});
});
</script>
Controller
- 우선, 세션정보가 없는 비회원 사용자가 상품 상세 페이지에서 찜하기를 눌렀을 경우 -1 을 리턴하여 "로그인이 필요한 서비스" 라고 제어 해준다.
- LikeVO 객체를 생성하여 사용자, 제품번호를 세팅해준 뒤 객체의 참조변수를 통해 insertLike()를 실행해준 뒤, result에 반환한 정수를 담아 다시 jsp 딴으로 보내버린다.
@ResponseBody
@RequestMapping(value="/like",method=RequestMethod.GET)
public int likePOST(ProductVO pvo,HttpSession session, Model model) {
//비회원인 사용자일 경우
int result=-1;
String user_id = (String)session.getAttribute("user_id");
if(user_id == null) {
return result;
}
// like객체 생성하여 값 세팅
LikeVO vo = new LikeVO();
vo.setBuyer_id(user_id);
vo.setProd_num(pvo.getProduct_num());
result = service.insertLike(vo);
session.setAttribute("result", result);
return result;
}
😂 이 부분에서 service 변수를 사용해서 실행하는 insertLike() ... <--- 이 명칭 대신 checkLike() 라고 했으면 구현하면서 덜 헷갈리고 뭘하는 메서드인지 직관적으로 확인할 수 있었을거 같다. 뒤에 로직을 보면 insertLike()에서 찜여부를 확인하고 그 결과에 따라 insert를 할지 delete를 할지 결정하는데 아무래도 이름을 잘못지은거 같다.
ServiceImpl
- vo에 담긴 정보(사용자, 제품번호)로, findLikeB(vo)를 실행하여 DB에 사용자가 해당 제품번호에 찜한 내역이 있나 찾고 LikeVO타입으로 리턴 받아 find에 저장한다.
- find 안에 데이터가 없을 경우 = 찜 하지 않은 상태 이므로 insertLike(vo) 를 실행한다.
- 그 외의 경우 = find 안에 데이터가 있을 경우 = 찜한 상태이므로 deleteLike(vo)를 실행한다.
- 실행 결과를 정수형으로 반환하여 insertLike()를 호출한 컨트롤러로 간다. → 컨트롤러는 리턴 받은 결과를 ajax로 호출한 jsp딴으로 보내버린다. → 반환한 정수형에 따라 로직 처리
@Override
public int insertLike(LikeVO vo) {
int result = 0;
LikeVO find = dao.findLikeB(vo);
if(find == null) { // find가 null일 경우 -> like 삽입 -> result=1
result = dao.insertLike(vo);
} else {
dao.deleteLike(vo); //find가 null이 아닐 경우 -> like 삭제 -> result = 0
}
return result;
}
Service, Impl / DAO, Impl / mapper
//좋아요 저장
public int insertLike(LikeVO vo);
//좋아요 저장
@Override
public int insertLike(LikeVO vo) {
int result = 0;
LikeVO find = dao.findLikeB(vo);
if(find == null) { // find가 null일 경우 -> like 삽입 -> result=1
result = dao.insertLike(vo);
} else {
dao.deleteLike(vo); //find가 null이 아닐 경우 -> like 삭제 -> result = 0
}
return result;
}
//좋아요 저장
public int insertLike(LikeVO vo);
//좋아요 확인
public LikeVO findLikeB(LikeVO vo);
//좋아요 삭제
public void deleteLike(LikeVO vo);
//좋아요 저장
@Override
public int insertLike(LikeVO vo) {
return sqlSession.insert(NAMESPACE + ".insertLike", vo);
}
//좋아요 확인
@Override
public LikeVO findLikeB(LikeVO vo) {
return sqlSession.selectOne(NAMESPACE + ".findLikeB", vo);
}
//좋아요 삭제
@Override
public void deleteLike(LikeVO vo) {
sqlSession.delete(NAMESPACE + ".deleteLike",vo);
}
<!-- 좋아요 저장 -->
<insert id="insertLike" >
insert into mfg_like(prod_num,buyer_id,`check`) values(#{prod_num},#{buyer_id},1)
</insert>
<!-- 좋아요 확인 -->
<select id="findLikeB" resultType="com.madforgolf.domain.LikeVO">
select * from mfg_like where prod_num=#{prod_num} and buyer_id=#{buyer_id}
</select>
<!-- 좋아요 삭제 -->
<delete id="deleteLike">
delete from mfg_like where prod_num=#{prod_num} and buyer_id=#{buyer_id}
</delete>
'코드 정리 > Spring Framework' 카테고리의 다른 글
7. SpringMVC - 페이징 처리 (0) | 2023.01.24 |
---|---|
6. SpringMVC - Ajax 통신을 통해 아이디 중복 체크 하기 (1) | 2023.01.17 |
4. Spring MVC - 주변 시설 찾기 (0) | 2023.01.11 |
3. Spring MVC - 카카오 우편서비스 API 사용 (0) | 2023.01.11 |
2. Spring MVC - 아이디 및 전화번호 중복체크 (0) | 2023.01.10 |