Notice
Recent Posts
Recent Comments
Link
반응형
250x250
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- java
- 웹
- 자바스크립트 기초
- 리액트프로젝트세팅
- HTML
- 처음만나는자바스크립트
- 구글캘린더api
- Spring Boot
- 자바
- 자바스크립트
- 자바스크립트기초문법
- js
- springboot
- 자바스크립트기초
- react
- CSS
- 전자정부 서버세팅
- Javascript
- 웹앱
- 스프링부트
- spring
- javaspring
- 구글 oauth
- 기초 코딩
- 리액트초기세팅
- 마이바티스
- 리액트세팅
- mybatis
- 코딩
- 기초코딩
Archives
- Today
- Total
인생 디벨로퍼
[Ajax] 좋아요 만들기! 본문
728x90
반응형
뷰 구현
jQuery 라이브러리 추가
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
하트 모양 이모티콘 추가
<i id="heart" class="fa-regular fa-heart fa-lg" value="no" style="margin-left: 3%;"></i>
클릭 모션 script
<script>
$("#heart").click(() => {
let value = $("#heart").val();
if (value == "ok") {
$("#heart").removeClass("fa-solid");
$("#heart").val("no");
} else {
$("#heart").addClass("fa-solid");
$("#heart").val("ok");
}
});
</script>
클릭시 하트가 채워진다
테이블 생성
create table love_tb(
id int auto_increment primary key,
board_id int not null,
user_id int not null,
created_at timestamp not null
);
모델링
package shop.mtcoding.newblog.model;
import java.sql.Timestamp;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Love {
private Integer id;
private Integer boardId;
private Integer userId;
private Timestamp createdAt;
}
package shop.mtcoding.newblog.model;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface LoveRepository {
public Love findByBoardIdAndUserIdLove(int boardId, int userId);
public List<Love> findAll();
public Love findById(int id);
public int insert(Love love);
public int updateById(Love love);
public int deleteById(int id);
}
board_id, user_id 로 조회 쿼리
select * from love_tb where board_id=1 and user_id=1;
참고 해, 매퍼 만들기
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="shop.mtcoding.newblog.model.LoveRepository">
<select id="findByBoardIdAndUserIdLove" resultType="shop.mtcoding.newblog.model.Love">
select * from board_tb
</select>
<select id="findAll" resultType="shop.mtcoding.newblog.model.Love">
select * from board_tb
</select>
<select id="findById" resultType="shop.mtcoding.newblog.model.Love">
select * from board_tb where id = #{id}
</select>
<insert id="insert">
insert into love_tb (board_id, user_id, created_at) values(#{boardId}, #{userId}, now())
</insert>
<delete id="deleteById" >
delete from love_tb where id = #{id}
</delete>
</mapper>
1. 좋아요 상태 보기
Controller
@GetMapping("/board/{id}")
public String detail(@PathVariable int id, Model model) {
User principal = (User) session.getAttribute("principal");
if (principal != null) {
Love love = loveRepository.findByBoardIdAndUserIdLove(id, principal.getId());
model.addAttribute("love", love);
}
BoardDetailRespDto board = boardService.글상세보기(id);
model.addAttribute("board", board);
List<ReplyDetailRespDto> replyDtoList = replyService.getReplyList(board.getId());
model.addAttribute("replyDtoList", replyDtoList);
return "board/detail";
}
jsp 수정
<div class="mb-2">
글 번호 : <span id="id"><i>${board.id}</i></span> 작성자 : <span><i>${board.username}</i></span>
<c:choose>
<c:when test="${love==null}">
<i id="heart" class="fa-regular fa-heart fa-lg" style="margin-left: 3%;"></i>
</c:when>
<c:otherwise>
<i id="heart" class="fa-solid fa-heart fa-lg" style="margin-left: 3%;"></i>
</c:otherwise>
</c:choose>
board id 와, principal id 가 있을경우 꽉찬 하트로 나타내기
2. 좋아요 on
Controller
@PostMapping("/love")
public @ResponseBody ResponseEntity<?> loveSave(@RequestBody LoveReqDto loveReqDto) {
User principal = (User) session.getAttribute("principal");
if (principal == null) {
throw new CustomApiException("인증이 필요합니다.", HttpStatus.BAD_REQUEST);
}
if (loveReqDto.getBoardId() == null) {
throw new CustomApiException("boardId를 전달해 주세요");
}
int loveId = loveService.좋아요(loveReqDto.getBoardId(), principal.getId());
return new ResponseEntity<>(new ResponseDto<>(1, "좋아요 성공", loveId), HttpStatus.OK);
}
json 으로 받아오기.
attr() 메서드는 선택자로 요소를 선택한 후, 해당 요소의 지정된 속성 값을 반환
insert 되며 생성된 'love id' 데이터 반환
Service
@Transactional
public int 좋아요(int boardId, int principalId) {
Board boardOP = boardRepository.findById(boardId);
if (boardOP == null) {
throw new CustomApiException("게시글이 존재하지 않습니다", HttpStatus.BAD_REQUEST);
}
Love love = new Love();
love.setBoardId(boardId);
love.setUserId(principalId);
loveRepository.insert(love);
return love.getId();
}
love 객체를 생성해서 board id 와 principal id 를 주입.
.xml
<insert id="insert" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
insert into love_tb (board_id, user_id, created_at) values(#{boardId}, #{userId}, now())
</insert>
- useGeneratedKeys="true": 이 속성은 자동 생성된 키를 사용할지 여부. 즉, 데이터베이스에서 자동으로 생성되는 키를 사용하도록 설정함.
- keyColumn="id": 이 속성은 자동 생성된 키가 저장될 컬럼의 이름.
- keyProperty="id": 이 속성은 자동 생성된 키가 매핑될 객체의 프로퍼티(property) 이름.
id 는 데이터 베이스에서 자동으로 생성 되도록 설정.
jsp
<div class="mb-2">
글 번호 : <span id="id"><i>${board.id}</i></span> 작성자 : <span><i>${board.username}</i></span>
<c:choose>
<c:when test="${love==null}">
<i id="heart" class="fa-regular fa-heart fa-lg" value="${love.id}" onClick="loveUpdate()" style="margin-left: 3%;"></i>
</c:when>
<c:otherwise>
<i id="heart" class="fa-solid fa-heart fa-lg" value="${love.id}" onClick="loveUpdate()" style="margin-left: 3%;"></i>
</c:otherwise>
</c:choose>
</div>
<script>
function loveUpdate() {
let boardId = $("#boardId").val();
let id = $("#heart").attr("value");
console.log(id);
if (id=="") {
let data = {boardId:boardId}
$.ajax({
type: "post",
url: "/love",
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
dataType: "json"
}).done((res) => { // 20X 일때
$("#heart").attr("value",res.data);
$("#heart").addClass("fa-solid");
$("#heart").removeClass("fa-regular");
}).fail((err) => {
alert(err.responseJSON.msg);
console.log("실패");
});
}
.attr 메소드로 value 값을 res.date 로 변경해줌
.addClass 메소드로 class 에 문장 추가.
.removeClass 메소드로 class 에 문장 삭제.
3. 좋아요 취소
Controller
@DeleteMapping("/love/{id}")
public @ResponseBody ResponseEntity<?> loveDelete(@PathVariable int id) {
User principal = (User) session.getAttribute("principal");
if (principal == null) {
throw new CustomApiException("인증이 필요합니다.", HttpStatus.BAD_REQUEST);
}
loveService.좋아요취소(id, principal.getId());
return new ResponseEntity<>(new ResponseDto<>(1, "좋아요 취소 성공", null), HttpStatus.OK);
}
Service
@Transactional
public void 좋아요취소(int id, int principalId) {
Love lovePS = loveRepository.findById(id);
if (lovePS == null) {
throw new CustomApiException("좋아요 내역이 존재하지 않습니다", HttpStatus.BAD_REQUEST);
}
if (lovePS.getUserId() != principalId) {
throw new CustomApiException("좋아요 취소 권한이 없습니다.", HttpStatus.BAD_REQUEST);
}
try {
loveRepository.deleteById(id);
} catch (Exception e) {
throw new CustomApiException("서버에 일시적인 문제가 생겼습니다.", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
jsp
else {
$.ajax({
type: "delete",
url: "/love/" + id,
dataType: "json"
}).done((res) => { // 20X 일때
$("#heart").attr("value",res.data);
$("#heart").removeClass("fa-solid");
$("#heart").addClass("fa-regular");
}).fail((err) => { // 40X, 50X 일때
alert(err.responseJSON.msg);
});
}
}
</script>
728x90
반응형
'JAVA Spring' 카테고리의 다른 글
Cookie 아이디 저장하기 (0) | 2023.06.18 |
---|---|
[Ajax] 비밀번호 확인 (0) | 2023.06.18 |
[Ajax] 썸네일 수정 contentType 설정 (0) | 2023.06.17 |
SHA-256 해시 함수 코드 (0) | 2023.05.12 |
spring 정리 (0) | 2023.05.09 |