Wanna be Brilliant Full-Stack Developer

2/15 SpringBoot 구독 모달 정보 API 만들기! #3 본문

Back-End/Spring Boot

2/15 SpringBoot 구독 모달 정보 API 만들기! #3

Flashpacker 2022. 2. 15. 18:42

목표

각자 펭지에서 구독정보를 누를떄 나오는 트리거에서 구독취소와 구독하기를 구현해보려고한다!

	<li><a href="javascript:subscribeInfoModalOpen();"> 구독정보<span>${dto.subscribeCount }</span>

구독정보를 클릭할때 subscribeInfoModalOpen() 이 오픈된다. 

이것은 또 어디있냐면 똑같이 profile.js에 있다. 

function subscribeInfoModalOpen() {
	$(".modal-subscribe").css("display", "flex");
}

modal-subscribe 라는 클래스를 찾아서 화면에 보여준다! 

modal-subscribe 어디있는가? 프로필.jsp 제일 밑에

<div class="modal-subscribe">
	<div class="subscribe">
		<div class="subscribe-header">
			<span>구독정보</span>
			<button onclick="modalClose()">
				<i class="fas fa-times"></i>
			</button>
		</div>

		<div class="subscribe-list" id="subscribeModalList">

			<div class="subscribe__item" id="subscribeModalItem-1">
				<div class="subscribe__img">
					<img src="#" onerror="this.src='/images/person.jpeg'" />
				</div>
				<div class="subscribe__text">
					<h2>love</h2>
				</div>
				<div class="subscribe__btn">
					<button class="cta blue" onclick="toggleSubscribeModal(this)">구독취소</button>
				</div>
			</div>


			<div class="subscribe__item" id="subscribeModalItem-2">
				<div class="subscribe__img">
					<img src="#" onerror="this.src='/images/person.jpeg'" />
				</div>
				<div class="subscribe__text">
					<h2>ssar</h2>
				</div>
				<div class="subscribe__btn">
					<button class="cta blue" onclick="toggleSubscribeModal(this)">구독취소</button>
				</div>
			</div>
		</div>
	</div>

</div>

구독정보를 눌렀을떄 우리가 들고와야하는정보는 profileImageUrl이랑 username이랑 내가 이사람을 구독했는지 안했ㄴ는지 정보가 필요하다. 여기서 잘봐야할것은 내가 ssar로 로그인했으면 2번페이지로 가면 2번페이지의 구독정보를 보는것이다. 이 구독취소 정보는 머냐면 지금 현재 로그인 ssar이 love를 구독했는지 안했는지 나와야한다! ssar이라는 얘가 로그인했는데 love를 구독안했으면 구독하기가 떠야한다! 

내가 로그인을 ssar로 했는데 cos가 구독한 정보가 ssar이 있으면 구독하기 구독취소 버튼이 보일 필요가 없다. 

 

이런정보를 뽑아오려면 이런 정보를 가지고 있는 DTO가 필요하다! 

int userid; 도 필요한데 로그인이 Ssar로 했는데 애를 구독취소하려면 쌀이 누군가를 구독취소를 해야하는데 누군가에대한 정보가 필요한데 그게 현재 love의 아이디값 

 

private Integer equalUserState; 지금 뜬 애가 로그인 한사람과 동일인인지 아닌지 그게 false면 보여주고 true면 구독상태가 안보이도록 할것이다.

구독상태인지 아닌지는 private Integer subscribeState; 애가 처리하고

private String profileImageUrl; 애는 사진 떄문에 필요하다! 

package com.cos.photogramstart.web.dto.subscribe;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public class SubscribeDto {
	private int userid;
	private String username;
	private String profileImageUrl;
	private Integer subscribeState;
	private Integer equalUserState;
}

이렇게 DTO를 만들고 그다음에 만들어야하는것이 SubscribeApi를 만들어야한다

어떤 API를 만들어야하 하냐면 user/1/subscribe하고 있는 정보가 필요하다 주소는 이런방식으로 만들것인데 

user 1 번이 구독하고 있는 정보를 어디에 만들거냐면!! 

UserApiController에 만들거다! 

	@GetMapping("/api/user/{pageUserId}/subscribe")
	public ResponseEntity<?> subscribeList(@PathVariable int pageUserId, @AuthenticationPrincipal PrincipalDetails principalDetails) {
		
		List<SubscribeDto> subscribeDto = null;
		
		return new ResponseEntity<>(new CMRespDto<>(1, "구독자 정보 리스트 가져오기 성공", subscribeDto),HttpStatus.OK);
	}

이렇게 만들고 그다음에 이제 서비스를 호출해야한다, subscribeService를 만들었기떄문에 DI를 할것이다! 

	private final UserService userService;
	private final SubscribeService subscribeService;
	
	@GetMapping("/api/user/{pageUserId}/subscribe")
	public ResponseEntity<?> subscribeList(@PathVariable int pageUserId, @AuthenticationPrincipal PrincipalDetails principalDetails) {
		
		List<SubscribeDto> subscribeDto = subscribeService.구독리스트(principalDetails.getUser().getId(), pageUserId);
		
		return new ResponseEntity<>(new CMRespDto<>(1, "구독자 정보 리스트 가져오기 성공", subscribeDto),HttpStatus.OK);
	}

이렇게 날려서 구독리스트를 받아올것이다. 구독리스트를 만들어야하는데! 

package com.cos.photogramstart.service;

import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cos.photogramstart.domain.subscribe.SubscribeRepository;
import com.cos.photogramstart.handler.ex.CustomApiException;
import com.cos.photogramstart.web.dto.subscribe.SubscribeDto;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Service
public class SubscribeService {
	
	private final SubscribeRepository subscribeRepository;
	
	
	@Transactional(readOnly = true)
	public List<SubscribeDto> 구독리스트(int principalId, int pageUserId) {
		
		
		
		return null;
	}

만들어주고 이제 해야 할것은 데이터베이스에서 셀렉트해서 SubscribeDto 이형태의 데이터를 받아오기만 하면된다! 

 


이제는 쿼리를 만드는 연습을 하려고하는데!

지금 우리가 뽑아야할 정보는 

유저 정보만 있는게 아니라 구독 여부와 내가 동일인이 아닌지 판단도 필요하다 ,내가 Ssar로 로그인했는데 구독정보를 봤는데 코스의 구독정보를 봤는데  ssar 이 있네 내가 여기서는 Ssar 로그인했으니까 구독정보가 보이면 안되는데 이러한 정보를 만드는것이 굉장히 어렵다.

 

이러한 정보를 쿼리를 통해서 만들어보려고한다! 

내가 만약 로그인을 쌀로 했으면 쌀로 로그인 상태에서 2번 코스한테 가면 

코스한테가서 코스가 구독하고있는 정보가 뜨면된다! 

 

1번가 3번을 출력하기 위해서는 

SELECT * FROM user; 유저정보가 전체가 다나와있는 상태에서 

내가 어떤 정보들만 뽑을거냐면 코스가 구독하고 있는 애들 1, 3 번  인 애들을 출력하려고한다 !

SELECT * FROM subscribe WHERE fromUserId = 2;

SELECT * FROM user WHERE id = 1 OR id = 3;

이 정보들을 뽑아야하는데 이런 쿼리로 하는것이 아니라 

SELECT * FROM user; 

SELECT * FROM subscribe WHERE fromUserId = 2; 이 두가지를 조인을 하는데

 조인 ( user.id = subscribe.toUserId)  유저의 아이디 1~3 중에 inner조인이라는 동일 조회 같은것들만 출력할것인데

subscribe에 1,3 과 같은 유저만 나와라! 

SELECT * 
FROM user u INNER JOIN subscribe s
ON u.id = s.toUserId 
WHERE s.fromUserId = 2; 2번이 구독하고 있는 toUserId를 찾아야하지 2번이 구독하지 않는 toUserid는 엄청많다. 

1 , 3 만 찾아야하기 위해서 ! 

두명의 유저가 잘보이는데 뽑아올떄는 이렇게 많은 정보는 필요없는데 

SELECT u.id, u.username, u.profileImageUrl
FROM user u INNER JOIN subscribe s
ON u.id = s.toUserId 
WHERE s.fromUserId = 2; 이렇게하여 

지금 사진과 이름만 가져올수있다.

ssar이 러브를 구독했는지 안했는지 구독여부가 필요하다. ssar이라는 유저가 1번을 구독했는지 안했는지

3번을 구독의 여부가 필요한데! 

내가 로그인을 1번으로 했으니 화면에는 1,3 번이 표시된다! 

내가 1번을 구독했는지 안했는지 여부는 자신이니 필요없고 3번이 1번을 구독했는지 여부를 확인해야한다. 

 

-- 가상 칼럼을 추가
SELECT u.id, u.username, u.profileImageUrl, 1 subscribeState
FROM user u INNER JOIN subscribe s
ON u.id = s.toUserId 
WHERE s.fromUserId = 2;

위에는 0, 밑에는 1로 만들어야한다!

우리는 스칼라 서브쿼리라는 걸 사용할거인데 

스칼라 서브쿼리가 머냐면 이 셀렉트 절에 셀렉트가 하나 더나오는것을 스칼라 서브쿼리라고 한다.

SELECT u.id, u.username, u.profileImageUrl,
(SELECT COUNT(*) FROM user) subscribeState
FROM user u INNER JOIN subscribe s
ON u.id = s.toUserId 
WHERE s.fromUserId = 2;

 

여기서 u.id를 통해서 비교만 하면된다.  SELECT true FROM subscribe WHERE fromUserId = 1 AND toUserId = 3;이거를 보면 1번과 3번만 비교해서 확인을 해주고 있는데 우리가 해야하는것은 1번과 1번도 비교해야하고 1번과 3번도 비교해야한다 그래서 변수가 들어가야한다.

-- 구독 여부 완성 쿼리

SELECT u.id, u.username, u.profileImageUrl,
(SELECT true FROM subscribe WHERE fromUserId = 1 AND toUserId = u.id) subscribeState
FROM user u INNER JOIN subscribe s
ON u.id = s.toUserId 
WHERE s.fromUserId = 2;

 

이제 해야하는것은 -

동일 유저인지 판단하는 쿼리가 필요하다.

SELECT u.id, u.username, u.profileImageUrl,
(SELECT true FROM subscribe WHERE fromUserId = 1 AND toUserId = u.id) subscribeState,
(1=u.id) equalUserState
FROM user u INNER JOIN subscribe s
ON u.id = s.toUserId 
WHERE s.fromUserId = 2;


이 쿼리로 무엇을 만들어낼수있냐면 저 위의 정보들을 SUbscribeDto에 있는정보들을 만들어낼수 있다.

이 쿼리써서 다음시간에 완성해보겠다!!