현재 kakao map을 이용해서
음식점 리뷰? 를 생각해서 간단하게 만들던 중,
소켓을 이용해서 좋아요가 얼마 이상인 경우
알림을 해주고 싶다고 갑자기 생각하게 돼서
일단 좋아요 버튼을 만들자!라고 생각해서
좋아요 테이블부터 체크까지만 포스팅하겠습니다.
------------------------------------------
먼저 기본 테이블입니다.
create table liketable(
ltmid varchar2(100) not null,
ltbid number not null,
ltlike number default 0,
FOREIGN KEY(ltmid) REFERENCES member(mid),
FOREIGN KEY(ltbid) REFERENCES board(bid)
)
일단 기본 구성입니다.
ltmid는 회원의 아이디
ltbid는 게시물 기본키,
ltlike는 좋아요를 체크하기 위한 값입니다.(눌렀을 경우 1 취소할 경우 0)
그리고 ltmid는 유저의 아이디의 외래 키,
ltbid는 게시판 번호를 외래 키로 받아와야 합니다.
이다음으로 생각해야 할 거는 좋아요 버튼 구현인데
여기서 좀 시간이 많이 걸렸습니다.
1. 좋아요 버튼을 누른 상태
2. 좋아요 버튼을 취소한 상태
이렇게 2가지를 생각했는데
'테이블에 update 할 row가 없는 경우?'
라는 생각이 들었고
insert를 해야한다 -> 어느 시점에? -> 상세보기를 눌렀을 때
라고 생각해서
특정 게시물을 클릭해서 상세보기에 들어간다면
그때 insert를 하기로 정했습니다.
즉, 좋아요는 총 3가지의 경우를 고려해야 한다.
이렇게 생각하고 먼저 mapper입니다.
<select id="ltlikecount" resultType="Integer" parameterType="kr.co.korea.beans.LikeBean">
select count(ltlike) from liketable where ltmid=#{ltmid} and ltbid=#{ltbid}
</select>
<insert id="likeinsert" parameterType="kr.co.korea.beans.LikeBean">
insert into liketable(ltmid,ltbid)
values (#{ltmid},#{ltbid})
</insert>
<select id="ltlikegetinfo" resultType="Integer" parameterType="kr.co.korea.beans.LikeBean">
select ltlike from liketable where ltmid=#{ltmid} and ltbid=#{ltbid}
</select>
<update id="likeupdate" parameterType="kr.co.korea.beans.LikeBean">
update liketable
set <include refid="cal"></include>
where ltmid=#{ltmid} and ltbid=#{ltbid}
</update>
<sql id="cal">
<if test="count == 1">
ltlike = 0
</if>
<if test="count == 0">
ltlike = ltlike + 1
</if>
</sql>
맨 위의 count로 테이블에
해당 유저의 좋아요에 대한 정보를 읽습니다.
없는 경우 insert
있는 경우에는 다시 select
그리고 update의 경우
2개의 sql문을 작성하려다가
따로 값을 줘서 구분하기로 했습니다.
bean입니다.
@Getter
@Setter
@ToString
public class LikeBean {
private String ltmid;
private int ltbid;
private int ltlike;
private int count;//좋아요가 눌린 상태인가 아닌가.
일단 lombok을 사용해서
어노테이션에 선언하는 것으로 해결하고
count로 게시물을 좋아요 눌렀는지 안 눌렀는지 체크합니다.
dao
@Autowired
private SqlSessionTemplate sqltemp;
public int ltlikecount(LikeBean likebean) {
return sqltemp.selectOne("like.ltlikecount",likebean);
}
public int ltlikegetinfo(LikeBean likebean) {
return sqltemp.selectOne("like.ltlikegetinfo",likebean);
}
public void likeinsert(LikeBean likebean) {
sqltemp.insert("like.likeinsert",likebean);
}
public void likeupdate(LikeBean likebean) {
sqltemp.update("like.likeupdate",likebean);
}
service
@Autowired
private LikeDao likedao;
public int ltlikecount(LikeBean likebean) {
return likedao.ltlikecount(likebean);
}
public int ltlikegetinfo(LikeBean likebean) {
return likedao.ltlikegetinfo(likebean);
}
public void likeinsert(LikeBean likebean) {
likedao.likeinsert(likebean);
}
public void likeupdate(LikeBean likebean) {
likedao.likeupdate(likebean);
}
그리고 controller는 먼저
2가지입니다.
하나는 게시판 controller,
다른 하나는 좋아요 버튼을 ajax의 비동기 방식으로 할 거기 때문에
restcontroller
먼저 boardcontroller입니다.
logger.info("boardread");
LikeBean likebean = new LikeBean();
likebean.setLtbid(bid);
likebean.setLtmid(currentUserName());
int ltlike = 0;
int check = likeservice.ltlikecount(likebean);
if(check ==0) {
likeservice.likeinsert(likebean);
}else if(check==1) {
ltlike = likeservice.ltlikegetinfo(likebean);
}
model.addAttribute("ltlike",ltlike);
먼저 boardcontroller의 상세보기 부분에서
좋아요 버트 부분만 작성한 것입니다.
bid는 게시물 번호
currentUserName은 스프링 시큐리티를 사용하고 있어서
유저의 아이디를 읽어오는 메서드를 따로 작성해놓은 것에 불러냅니다.
그 후,
count를 호출하여 0일 경우 해당 유저의 아이디와 게시물 번호로 insert 해주고
만약 값이 있을 경우에는
사전에 선언해둔 ltlike로 선언해줍니다.
insert의 경우 default 0으로 해두었고
ltlike가 사전에 0으로 설정해두었기 때문에 따로 할 필요가 없습니다.
그리고 likeRestController입니다.
@PutMapping("/likeupdate")
public Map<String,String> likeupdate(@RequestBody LikeBean likebean){
logger.info("likeupdate");
Map<String,String> map = new HashMap<String, String>();
try {
likeservice.likeupdate(likebean);
map.put("result", "success");
}catch(Exception e) {
e.printStackTrace();
map.put("result", "fail");
}
return map;
}
@putmapping은 @post로 바꾸셔서 하셔도 됩니다.
저건 RestApi에 조금 더 익숙해지려고
사용한 거라서.... Postmapping으로 바꾸셔도 됩니다.
그 후 view
<td id="like">
<c:choose>
<c:when test="${ltlike ==0}">
<button type="button" class="btn btn-light" id="likebtn">좋아요</button>
<input type="hidden" id="likecheck" value="${ltlike }">
</c:when>
<c:when test="${ltlike ==1}">
<button type="button" class="btn btn-danger" id="likebtn">좋아요</button>
<input type="hidden" id="likecheck" value="${ltlike }">
</c:when>
</c:choose>
</td>
일단 좋아요 버튼은
어떠한 사람이라도 보이게 했기 때문에
boardcontroller에서 설정해준 값으로
해당 버튼의 색깔과 hidden의 값을 설정해주었습니다.
그 후 ajax
$('#likebtn').click(function(){
likeupdate();
});
function likeupdate(){
var root = getContextPath(),
likeurl = "/like/likeupdate",
mid = $('#mid').val(),
bid = $('#bid').val(),
count = $('#likecheck').val(),
data = {"ltmid" : mid,
"ltbid" : bid,
"count" : count};
$.ajax({
url : root + likeurl,
type : 'PUT',
contentType: 'application/json',
data : JSON.stringify(data),
success : function(result){
console.log("수정" + result.result);
if(count == 1){
console.log("좋아요 취소");
$('#likecheck').val(0);
$('#likebtn').attr('class','btn btn-light');
}else if(count == 0){
console.log("좋아요!");
$('#likecheck').val(1);
$('#likebtn').attr('class','btn btn-danger');
}
}, error : function(result){
console.log("에러" + result.result)
}
});
};
function getContextPath() {
var hostIndex = location.href.indexOf( location.host ) + location.host.length;
return location.href.substring( hostIndex, location.href.indexOf('/', hostIndex + 1) );
}
PostMapping의 경우에는 type를 POST로 바꾸면 됩니다.
이렇게 설정을 한 뒤 확인을 해보면
이렇게 insert가 된 것을 확인할 수 있고
여기에서 좋아요 버튼을 누르면
버튼의 색이 바뀌었고
ltlike의 값이 바뀐 것을 확인할 수 있다.
여기에서 한번 더 누르면
제대로 작동하고 있는 것을 확인할 수 있습니다.
'spring > 게시판' 카테고리의 다른 글
스프링 웹 소켓 좋아요 알림(1) (0) | 2021.04.28 |
---|---|
스프링 게시판 만들기 좋아요(2) (0) | 2021.04.24 |
스프링 Rest CRUD 구현 (0) | 2021.04.07 |
스프링 시큐리티 예제 (0) | 2021.04.07 |
스프링 이미지 업로드 (0) | 2021.03.11 |