Spring Boot

SpringBoot + MariaDB 7-1 스토리 렌더링

svdjcuwg4638 2023. 6. 13. 20:32

스토리 렌더링

메인페이지의 스토리 게시물을 올릴려하는데 무었을 가져와야할까?

user의 이미지와 이름 그리고 캡션 

다른 좋아요와 댓글은 아직 구현안했으니 이정도만 가져와보자.

 

그럼 image클래스 객체를 가져올 것인데 객체의 멤버필드를 보면

	// User의 images리스트는 필요없으니 제외시킴
	@JsonIgnoreProperties({"images"})
	@JoinColumn(name="userId")
	@ManyToOne
	private User user;

이미지는 개별로 다들고와서 이미 존재하는상태라 user의 images리스트를 받을 필요가없다 그래서 @JsonIgnoreProperties를 이용하여 제외시킨 모습이다.

 

domain.image.ImageRepository.java 인터페이스

밑과 같은 DB요청문 추가해주기

쿼리문을 추가할때 

내가 2번일때 1번과 3번의 이미지를 보고싶다면 밑과 같은 sql문이 완성될것이고

SELECT * FROM image WHERE userId IN(1,3);

 

2번이 구독한 사람을 보고싶다면 밑과 같은 sql문이 보일것이다 
SELECT toUserId FROM subscribe WHERE fromUserId =2

 

그렇다면 이두개를 합치면 2번이 구독한사람의 이미지만 뽑을 수 있지 않을까?

in안에 서브쿼리를 이용하면 되는것이다 알았으니 바로 적용시켜 코드를 작성해보자

package com.cos.photogramstart.domain.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> mStrory(int principalId);
}

 

service.ImageSerivce.java

이미지 서비스에 함수 추가

	private final ImageRepository imageRepository;
	
	@Transactional(readOnly = true) // 영속성 컨텍스트 변경 감지를 해서, 더티체킹 flush(반영) x
	public List<Image> 이미스토리(int principalId){
		List<Image> images = imageRepository.mStrory(principalId);
		return images;
	}

 

 

web.api.ImageApiController.java

api요청할 컨트롤러 생성해주기

package com.cos.photogramstart.web.api;

@RequiredArgsConstructor
@RestController
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);
	}
}

여기 까지 하였다면 게시물데이터를 가져온것은 끝이다

postman으로 로그인하여서 확인해보니 데이터가 잘 들어오는것을 확인하였다 

 

이제 가져온 데이터를 스토리화면에 출력해보자

 

story.js

우선 html코드를 작성해보자

function getStoryItem(image) {
// onerror는 만약 사진이없다면 이사진으로 대체하는 기능이다.
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;
}

 

위 html코드를 받아 append해줄 함수는 이러하다

// (1) 스토리 로드하기
function storyLoad() {

	$.ajax({
		url : `/api/image/`,
		dataType : "json"
	}).done(res=>{
		console.log(res);
		res.data.forEach((image)=>{
			let stoyItem = getStoryItem(image);
			$("#storyList").append(stoyItem);
		})
	}).fail(err=>{
		console.log("오류",err)
	})

}

storyLoad();

위 url을 요청하면 로그인한 사람의 기준으로 구독중인 사람의 게시물을 모두 가져와 처리

storyLoad(); 가 단독으로 밑에 적힌건 실행시키기 위함 버튼이나 이런이벤트가아니라 페이지가 로드되면 실행되야하기 때문에

 

이러면 스토리게시물 렌더링 끝!