β Spring FrameWork 좋아요 기능

@Autowired·2021년 12월 29일
6

Spring Framework

목록 보기
2/6
post-custom-banner

Spring FrameWork에서 좋아요 기능을 간단하게 구현하는 방법입니다.

  • 참고사항 (필독!)
    • 개발환경 : Mac
    • DB : MySQL
    • 게시글번호 & 회원번호 : long
    • 테이블 이름 : exhibition_table(게시판) & member_table(회원)
    • mybatis-config.xml : HeartDTO를 hdto로 선언
    • 좋아요를 누를 시 heart가 1로 변경, 취소 시 저장된 데이터 삭제하는 방식
    • 좋아요 갯수 세는 것 제외 (좋아요 기능만 정리)
    • 코드는 본인거에 맞게 수정해서 쓰세요~

DB table (게시판&회원 참고용)

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)
);

DB heart_table 생성

create table heart_table (
	-- pk값으로 쓸 컬럼
	h_number bigint auto_increment,
	-- 게시글 번호
	e_number bigint,
	-- 회원 번호
	m_number bigint,
	-- 좋아요
	heart int,
	constraint primary key(h_number)
);

HeartDTO 생성

@Data
public class HeartDTO {
	// pk값으로 쓸 번호
	private long h_number;
	// 게시글 번호
	private long e_number;
	// 회원 번호
	private long m_number;
	// 좋아요
	private int heart;
}

@Controller

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";
}

@Service

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);
}

@Repository

public HeartDTO findHeart(Map<String, Long> number) {
	return sql.selectOne("Exhibition.findHeart",number);
}

mapper

<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가 출력됨.


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>

@Controller

AJAX에서 요청한 정보를 받아서 처리후 보내는 메서드

@RequestMapping(value="heart",method=RequestMethod.POST)
public @ResponseBody int heart(@ModelAttribute HeartDTO heart) {
	int result = es.insertHeart(heart);
	return result;
}

@Service

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;
}

@Repository

// 좋아요가 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);
}

mapper

// 좋아요 확인
<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

profile
즐겁다!
post-custom-banner

0개의 댓글