Spring/JPA + Security
[Spring Data JPA] 포토 게시판 페이지 구현하기 - 2 포토리스트 띄우기 및 Ajax를 통한 뷰 렌더링
pyogowoon
2023. 1. 12. 12:28
-1 에서 스칼라 쿼리로 만든 DB를 통해서 포토리스트를 띄울 예정이다.
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.pyo.yourspick.domain.user.User;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.time.LocalDateTime;
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
@Entity
public class Image {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private int id;
private String caption;
private String postImageUrl;
@JsonIgnoreProperties({"images"})
@ManyToOne
@JoinColumn(name = "userId")
private User user;
private LocalDateTime createDate;
@PrePersist
public void createDate(){
this.createDate = LocalDateTime.now();
}
}
우선 우리는 Image 도메인을 매개로 DB와 연결될것인데,
private User user; 위에 @JsonIgnoreProperties({"images"}) 를 붙여준다. 이유는 User를 Object로 가져오기 때문에
User.class 안에서도 또 image를 참조하기 때문에 무한참조가 일어나는데 이를 방지하기 위해서 붙여준다.
public interface ImageRepository extends JpaRepository<Image, Integer> {
@Query(value="SELECT * FROM image WHERE userId IN (SELECT toUserId FROM subscribe WHERE fromUserId = :principalId);", nativeQuery = true)
List<Image> mStroy(@Param("principalId") int principalId);
}
우선 만든 쿼리를 네이티브 쿼리를 통해 Repository에 등록한다.
image를 List로 받을것이며 principalId를 사용할 것
그 후
public class ImageApiController {
private final ImageService imageService;
@GetMapping("/api/image")
public ResponseEntity<?> imageStroy(@AuthenticationPrincipal PrincipalDetails principalDetails) {
List<Image> images = imageService.이미지스토리(principalDetails.getUser().getId());
return new ResponseEntity<>(new CMRespDto<>(1,"성공",images), HttpStatus.OK);
}
}
컨트롤러 단에서 서비스로 넘긴다.
@Transactional(readOnly = true)
public List<Image> 이미지스토리(int principalId) {
List<Image> images = imageRepository.mStroy(principalId);
return images;
}
ImageService 에서 Repository를 불러준다.
이제 뷰 렌더링을 위한 AJAX를 한다
story.js
function storyLoad() {
$.ajax({
type:"get",
url:`/api/image`,
dataType:"json"
}).done(res =>{
console.log(res, "성공");
res.data.forEach((image) =>{
let storyItem = getStoryItem(image);
$("#storyList").append(storyItem);
});
}).fail(error =>{
console.log(error,"실패");
});
}
storyLoad();
story.jsp
<div class="story-list__item">
<div class="sl__item__header">
<div>
<img class="profile-image" src="#"
onerror="this.src='/images/person.jpeg'" />
</div>
<div>TherePrograming</div>
</div>
<div class="sl__item__img">
<img src="/images/home.jpg" />
</div>
<div class="sl__item__contents">
<div class="sl__item__contents__icon">
<button>
<i class="fas fa-heart active" id="storyLikeIcon-1" onclick="toggleLike()"></i>
</button>
</div>
<span class="like"><b id="storyLikeCount-1">3 </b>likes</span>
<div class="sl__item__contents__content">
<p>등산하는 것이 너무 재밌네요</p>
</div>
<div id="storyCommentList-1">
<div class="sl__item__contents__comment" id="storyCommentItem-1"">
<p>
<b>Lovely :</b> 부럽습니다.
</p>
<button>
<i class="fas fa-times"></i>
</button>
</div>
</div>
<div class="sl__item__input">
<input type="text" placeholder="댓글 달기..." id="storyCommentInput-1" />
<button type="button" onClick="addComment()">게시</button>
</div>
</div>
</div>
추후 데이터를 담아서 불러올 리스트 부분을 모조리 ctrl + x 로 잘라낸다.
그 후
story.js
function getStoryItem(image) {
let item=`
<div class="story-list__item">
<div class="sl__item__header">
<div>
<img class="profile-image" src="/upload/${image.user.profileImageUrl}"
onerror="this.src='/images/person.jpeg'" />
</div>
<div>${image.user.username}</div>
</div>
<div class="sl__item__img">
<img src="/upload/${image.postImageUrl}" />
</div>
<div class="sl__item__contents">
<div class="sl__item__contents__icon">
<button>
<i class="fas fa-heart active" id="storyLikeIcon-1" onclick="toggleLike()"></i>
</button>
</div>
<span class="like"><b id="storyLikeCount-1">3 </b>likes</span>
<div class="sl__item__contents__content">
<p>${image.caption}</p>
</div>
<div id="storyCommentList-1">
<div class="sl__item__contents__comment" id="storyCommentItem-1"">
<p>
<b>Lovely :</b> 부럽습니다.
</p>
<button>
<i class="fas fa-times"></i>
</button>
</div>
</div>
<div class="sl__item__input">
<input type="text" placeholder="댓글 달기..." id="storyCommentInput-1" />
<button type="button" onClick="addComment()">게시</button>
</div>
</div>
</div>`;
return item;
}
ajax 에서 반복문을 담은 함수를 하나 만들고 백틱과 EL태그 이용해서 데이터넘겨준다.

데이터가 잘 넘어온다.