좋아요의 뷰를 구현하고자 한다. 빈 하트를 클릭하면 빨갛게 채워진 하트가 되어야 하고, 새로고침이나 로그인 시
이전에 좋아요 했던 인원들은 이미 빨갛게 채워진 하트가 되어있어야 한다.
즉 이전에 포토 스토리 뷰를 ajax로 렌더링 할 때,
DB에서 좋아요의 현황도 가져와야 한다.
story.js
function storyLoad() {
$.ajax({
type:"get",
url:`/api/image?page=${page}`,
dataType:"json"
}).done(res =>{
console.log(res, "성공");
res.data.content.forEach((image) =>{
let storyItem = getStoryItem(image);
$("#storyList").append(storyItem);
});
}).fail(error =>{
console.log(error,"실패");
});
}
storyLoad();
이전에 구현한 ajax 에서 여기서 foreach 돌린 image 안에 있는 likes 정보를 가져와야 한다.
ImageService
@Transactional(readOnly = true)
public Page<Image> 이미지스토리(int principalId , Pageable pageable){
imageRepository.findById(principalId).orElseThrow(()->{
throw new CustomApiException("아이디를 찾을 수 없습니다.");
});
Page<Image> images = imageRepository.mStory(principalId, pageable);
return images;
}
결국 이전에 만든 ImageService 에서 어떻게든 likes 정보를 가져와야 한다.
그러나 Image 도메인에는 likes를 만든적이 없다,
그러므로 Image에 likes 양방향 맵핑을 만들어야 한다.
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
@Entity
public class Image {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String caption;
private String postImageUrl; // 사진을 전송받아서 그 사진을 서버에
// 폴더에 저장하게될것 - DB에는 경로를 인서트
@JsonIgnoreProperties({"images"})
@JoinColumn(name="userId") //foreign 키 이름 지정
@ManyToOne // 한명이 많은 이미지를 올릴 수 있고 이미지는 하나의 이미지가 여럿일수없으니
private User user; // db에 오브젝트 자체를 저장할 순 없고 이대로면 foreign key로 저장됨
//이미지 좋아요
// image를 셀렉트할떄 likes 정보를 같이 들고옴
@JsonIgnoreProperties({"image"})
@OneToMany(mappedBy="image") //likes의 image변수 이름
private List<Likes> likes;
//이미지 댓글
private LocalDateTime createDate;
@Transient // DB에 칼럼이 만들어지지않는다
private boolean likeState;
@Transient
private int likeCount;
@PrePersist
public void createDate() {
this.createDate = LocalDateTime.now();
}
}
Image 도메인에 List<Likes> likes 를 추가해주었다, 하나의 이미지에 좋아요는 수백개 수천개 있을 수 있으니
List로 받았다.
Image 도메인에 likeState , likeCount 를 추가하였고
@OneToMany(mappedBy = "image") 를 걸어주었다, 여기서 Image는 Likes 의 필드인 image의 변수값이다.
@Transient 어노테이션을 통해 DB에 칼럼을 만들지 않고 참조만 하도록 설정 해주었고 (이친구 아주 유용)
스크롤 페이징에서 무한참조가 되는 오류가 발생하였기에
likes 컬럼에 @JsonIgnoreProperties 어노테이션을 추가.(양방향 맵핑시에 꼭 붙이자.)
imageService 에 이미지 스토리에 forEach문 추가.
ImageService
@Transactional(readOnly = true)
public Page<Image> 이미지스토리(int principalId , Pageable pageable){
imageRepository.findById(principalId).orElseThrow(()->{
throw new CustomApiException("아이디를 찾을 수 없습니다.");
});
Page<Image> images = imageRepository.mStory(principalId, pageable);
images.forEach((image) ->{
image.getLikes().forEach((like) ->{
if(like.getUser().getId() == principalId){
image.setLikeState(true);
}
});
});
return images;
}
기존의 이미지스토리 로직에서 foreach문을 돌리는 로직을 추가하였다,
forEach로 Likes의 정보를 모두 나열한 후 Likes의 id와 로그인한 아이디(PrincipalId) 가 같으면
likeState를 true로 해주는 로직이다.
.
.
.
.
<div class="sl__item__img">
<img src="/upload/${image.postImageUrl}" />
</div>
<div class="sl__item__contents">
<div class="sl__item__contents__icon">
<button>`;
if(image.likeState){
item +=`<i class="fas fa-heart active" id="storyLikeIcon-${image.id}" onclick="toggleLike(${image.id})"></i>`
}else{
item += `<i class="far fa-heart" id="storyLikeIcon-${image.id}" onclick="toggleLike(${image.id})"></i>`
}
item +=`
</button>
</div>
기존에 있던 HTML 영역을 백틱으로 닫아주고 if~ 부터는 JS영역으로 최초 홈페이지 실행시 빈 하트가 뜰 수 있도록 처리한다.
이제 좋아요 상태에 따라 빈하트와 빨간하트가 잘 작동된다.
이제 좋아요 카운트 뷰 렌더링만 하면 된다.
ImageService
@Transactional(readOnly = true)
public Page<Image> 이미지스토리(int principalId , Pageable pageable){
imageRepository.findById(principalId).orElseThrow(()->{
throw new CustomApiException("아이디를 찾을 수 없습니다.");
});
Page<Image> images = imageRepository.mStory(principalId, pageable);
images.forEach((image) ->{
image.setLikeCount(image.getLikes().size());
image.getLikes().forEach((like) ->{
if(like.getUser().getId() == principalId){
image.setLikeState(true);
}
});
});
return images;
}
카운트의 경우 간단하게 likes의 사이즈를 likeCount 에 set 해주면 된다.
story.js
<span class="like"><b id="storyLikeCount-${image.id}">${image.likeCount}</b>likes</span>
js에도 연결해주고
likes 의 갯수도 잘 나온다.
하지만 아직 비동기 렌더링은 진행하지 않았다.
당연히 좋아요를 누르면 카운트가 바로 올라가야 하는 로직을 구현해야만 한다.
-4에서 계속...
'Spring > JPA + Security' 카테고리의 다른 글
[Spring Data JPA] 좋아요 구현하기 번외 무한참조 오류 잡기 (0) | 2023.01.13 |
---|---|
[Spring Data JPA]좋아요 구현하기 -4 Ajax 연결 후 마무리하기 (0) | 2023.01.13 |
[Spring Data JPA] 좋아요 구현하기 - 2 좋아요 api 구현 (0) | 2023.01.12 |
[Spring Data JPA] 좋아요 구현하기 - 1 모델 만들기 (0) | 2023.01.12 |
[Spring Data JPA] 포토 게시판 페이지 구현하기 -3 JPA 페이징 처리 예제 (0) | 2023.01.12 |
댓글