티스토리 뷰
댓글을 이제 DB에서 가져와 보여줘야하는데 우리가 스토리에 게시물을 가져올때 Image를 가져오고있으니 Image에 댓글을 추가해주자
Image.java
@JsonIgnoreProperties({"image"})
@OneToMany(mappedBy = "image") // 연관관계의 주인이 아니다 명시
private List<Comment> comments;
위와같이 추가해주고 image는 가져올 필요도없고(이미 가져왔으니) 무한참조가 생길께 뻔하니 Ignore해주자
이번엔 하나의 이미지에 여러 댓글이 담길수있다 Image가 주이니 OneToMany가 되게된다.
편하게 생각할려면 양방향 매핑때는 무조건 주에 OneToMany라고 기억하자
mappedBy = "image"의 뜻은
우선 Comment의 필드를 보면
@JoinColumn(name="imageId")
@ManyToOne(fetch = FetchType.EAGER)
private Image image;
Image의 imageId를 부모키로 참조하고있다 즉 내가 가지고있는 image는 내가 부모가아니다 라는 뜻이게된다 난참조만 할 뿐이다 라는뜻이다
이제 js를 만들어보자
image.comments.forEach((comment)=>{
item +=`
<div class="sl__item__contents__comment" id="storyCommentItem-${comment.id}">
<p>
<b>${comment.user.username}</b>${comment.content}
</p>
<button>
<i class=" fas fa-times"></i>
</button>
</div>
`;
});
이미 스토리에 게시물을 image라고 불러오고있으니 그걸이용해 image의 데이터만 가져오게 되면 완성된다
정렬
preappend 하여 맨위에 댓글이 잘달리지만 새로고침을 하게되면 우리가 원했던거랑 달리 거꾸로 출력이된다 즉 오래된 댓글이 맨위로 오게되는것이다
그럼 DESC형태로 불러오도록 설정해주자 이미지로가자
Image.java
// 이미지 댓글
@OrderBy("id DESC")
@JsonIgnoreProperties({"image"})
@OneToMany(mappedBy = "image") // 연관관계의 주인이 아니다 명시
private List<Comment> comments;
위와같이 id DESC형태로 가져오게되면 id기준으로 DESC정렬을 하여 데이터를 가져오게된다 설정하고 다시 출력하면은 원하는대로 제일 최신댓글이 위로 오는모습을 확인할 수 있다.
삭제
세션 정보 가져오기
댓글 삭제 기능을 수행할려하는데 댓글은 본인이 작성한 댓글만 삭제가 가능하여야한다 그럴려면 세션의 아이디가 필요한데 현재 댓글을 불러오는 js함수에는 세션을 받아오고있지않아 곤란한 상황이다 세션의 아이디를 js가져와보자
header.jsp
<!-- 세션에 데이터를 가져오는 코드 -->
<sec:authorize access="isAuthenticated()">
<!-- property는 고정으로 principal을 사용한다 제작자가 그렇게 정의해놨음 -->
<sec:authentication property="principal" var="principal"/>
</sec:authorize>
저번에 작성했던 세션의 데이터를 가져와 principal에 세션의 데이터를 저장하는 코드이다 이코드는 jsp에서만 사용가능했고 우리가 js에서 사용할려면 매개변수값으로 넣어주거나 했었다 하지만 매개변수에 기입하지 않아도 js에서 사용할 수 있도록 설정해보자
header.jsp
<body>
<!-- principalId담아두는 곳 -->
<input type="hidden" id="principalId" value="${principal.user.id }">
해더jsp의 바디 바로밑에 만들어주고 id가 princiaplId인 것의 값을 가져오면 되는것이다 바로 가져와보자
sotry.js
let principalId = $("#principalId").val();
사용이 필요한 js파일 상단에 위와 같이 명시해둔다면 어느 함수에서든 세션의 아이디를 불러올 수 있도록 설정이된다.
삭제버튼 작성자만 보이게
이제 id를 불러왔으니 댓글의 id와 세션의 id만 비교해서 버튼이 보이게 안보이게만 적용해주면 될거같다.
image.comments.forEach((comment)=>{
item +=`
<div class="sl__item__contents__comment" id="storyCommentItem-${comment.id}">
<p>
<b>${comment.user.username}</b>${comment.content}
</p>`;
if(principalId == comment.user.id){
item +=
`
<button>
<i class=" fas fa-times"></i>
</button>
`
}
item +=
`</div>`
;
});
아까 작성한 댓글불러오는 코드에서 if문만 추가해주면 되는것이다 이제 확인을 해보면 내가 작성한 댓글만 x가 보인다면 성공!
삭제 버튼 작동하게하기
삭제를 할려면 id만 받오면되니 id만 매개변수에 넣어 버튼에 onclick이벤트를 걸어주자
<button onclick="deleteComment(${comment.id})">
<i class=" fas fa-times"></i>
</button>
위와같이 만들어주고 이제 컨트롤러에 요청 만들러가보자
CommentApiController.java
@DeleteMapping("/api/comment/{id}")
public ResponseEntity<?> commentDelete(@PathVariable int id){
commentService.댓글삭제(id);
return new ResponseEntity<>(new CMRespDto<>(1,"댓글삭제성공",null),HttpStatus.OK);
}
CommentService.java
@Transactional
public void 댓글삭제(int id) {
try {
commentRepository.deleteById(id);
}catch(Exception e){
throw new CustomApiException(e.getMessage());
}
}
오류가 나진 않지만 오류가 발생한다면 CustomApiException으로 에러를 잡아주자 데이터만 들어가는것이니 Api를 사용했습니다.
js함수
function deleteComment(commentId) {
$.ajax({
type:"delete",
url:`/api/comment/${commentId}`,
dataType:"json"
}).done(res=>{
console.log("성공",res)
$(`#storyCommentItem-${commentId}`).remove();
}).fail(err=>{
console.log("실패",err)
})
}
이제 삭제버튼을 누른다면 실시간으로 삭제되는것이 보일것이다.
근대 내가 방금 적은 댓글의 삭제버튼을 하니 적용이 안된다 그렇다는건 내가 댓글을 작성하고 append해주는곳에서 잘못된거같다 밑과같이 수정해주자
let content = `
<div class="sl__item__contents__comment" id="storyCommentItem-${comment.id}">
<p>
<b>${comment.user.username}</b>
${comment.content}
</p>
<button onclick="deleteComment(${comment.id})"><i class="fas fa-times"></i></button>
</div>
`;
button에 이벤트가 안달려서 생성되니 당연한것이다 불러올때만 생성하지말고 댓글이 추가될때도 이벤트를 넣어주자
'Spring Boot' 카테고리의 다른 글
SpringBoot + MariaDB 11 AOP자동에러처리(Spring AOP) (0) | 2023.06.15 |
---|---|
SpringBoot + MariaDB 10-3 댓글 유효성 검사(@NotNull,Blank,Empty) (0) | 2023.06.15 |
Exception, ApiException, ValidationException정리 (0) | 2023.06.15 |
SpringBoot + MariaDB 10-2 댓글 작성(가짜 클래스) JSON.stringify (0) | 2023.06.14 |
SpringBoot + MariaDB 10-1 댓글 모델(LAZY,EAGER 선택) (0) | 2023.06.14 |