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태그 이용해서 데이터넘겨준다.

 

 

 

 

 

 

데이터가 잘 넘어온다.