반응형

메인화면에서 보일 페이지를 구성할거다.
유저정보, 이미지url, 캡션, like정보, 댓글 정보가 필요한데 일단 유저정보, 이미지정보, 캡션 정보만 보이게할거다.

시나리오:
2번으로 로그인해서 메인 페이지(피드)를 본다.

따라서 다음과 같이 userId가 1,3인 이미지 정보만 봐야한다.

IN 내부에 직접 적는건 무리가 있으니까
2번 follow 테이블에서 fromUserId(로그인한 유저)의 아이디가 팔로우 하는 유저의 정보를 가져오는 쿼리를 짜고

 

그쿼리를 아까 이미지를 SELECT하는 쿼리의 서브쿼리로 넣어준다.

 

Image.class
이미지를 조회했을때 User 객체의 image정보를 또 들고올 수 있으니까 
@JsonIgnoreProperties({"images"}) 를 통해 User의 image정보는 가져오지 않게 한다.

@Builder
@AllArgsConstructor
@NoArgsConstructor
@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") // DB컬럼명 설정
    @ManyToOne(fetch = FetchType.EAGER)
    private User user;

    //이미지 좋아요 정보

    //댓글

    private LocalDateTime createDate;

    @PrePersist
    public void createDate(){
        this.createDate = LocalDateTime.now();
    }

 

ImageRepository

public interface ImageRepository extends JpaRepository<Image, Integer> {

    //로그인 한 사람이 자신을 제외한 다른 유저들의 사진을 구하는 쿼리
    @Query(value = "SELECT * FROM image WHERE userId IN (SELECT toUserId FROM follow WHERE fromUserId = :principalId) ORDER BY id DESC;", nativeQuery = true)
    List<Image> mStory(int principalId);

}

 

ImageApiController
-로그인 유저정보를 imageServicedml imageStory 메소드매개변수로 전달해준다.

@RequiredArgsConstructor
@RestController
public class ImageApiController {

    private final ImageService imageService;

    @GetMapping("/api/image")
    public ResponseEntity<?>imageStory(@AuthenticationPrincipal PrincipalDetails principalDetails
    ){
        List<Image> images = imageService.imageStory(principalDetails.getUser().getId());

        return new ResponseEntity<>(new CMRespDto<>(1, "성공", images), HttpStatus.OK);
    }

   

}

 

ImageService

@RequiredArgsConstructor
@Service
public class ImageService {

    private final ImageRepository imageRepository;

    @Transactional(readOnly = true)
    public List<Image>imageStory(int principalId){
        List<Image> images = imageRepository.mStory(principalId);

        return images;
    }

 ...
    }
}

 

story.html
- story.js를 로드한다.

<html xmlns:th="http://www.thymeleaf.org">

<!--<%@ include file="../layout/header.jsp"%>-->
<div th:replace="layout/header" :: menu />
<main class="main">
    <section class="container">
        <!--전체 리스트 시작-->
        <article class="story-list" id="storyList">

            <!--전체 리스트 아이템-->


        </article>
    </section>
</main>
<script src="/js/story.js"></script>
</body>
</html>

 

story.js
- url은 '/api/image' 로 요청
- 응답받은 결과를 for문 돌면서 getStoryItem() 함수의 매개변수로 넣어주고
 그 결과(storyItem)을 html id값 'storyList'에 append해 준다.

// (1) 스토리 로드하기
function storyLoad() {
    $.ajax({
        url:`/api/image`,
        ataType : "json"
    }).done(res=>{
        console.log(res);
        res.data.forEach((image) => {
            let storyItem = getStoryItem(image)
            $("#storyList").append(storyItem);

        })
    }).fail(error => {
        console.log("오류", error);

    });
}

storyLoad();
function getStoryItem(image) {
    let item =
    `<div class="story-list__item">
         <div class="sl__item__header">
             <div>
                 <img class="profile-image" src="/${image.user.profileImageUrl}"
                      onerror="this.src='/images/person.jpeg'" />
             </div>
             <div>${image.user.username}</div>
         </div>

         <div class="sl__item__img">
             <img src="/${image.postImageUrl}" />
         </div>

         <div class="sl__item__contents">
             <div class="sl__item__contents__icon">

                 <button>
                     <i class="fas fa-heart active" id="storyLikeIcon-${image.id}" onclick="toggleLike(${image.id})"></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

}

 

+ Recent posts