Wanna be Brilliant Full-Stack Developer
2/15 SpringBoot 구독정보 완성하기 #1 본문
목표
구독자수 랜더링하는것을 해보려고한다!
내 구독자수 확인과 상대방 user에게 갔을떄 구독할떄와 취소할때 구독자수 랜더링도 적용해보려고한다
처음에는 UserProfileDto에 두가지를 추가해야한다!
package com.cos.photogramstart.web.dto.user;
import com.cos.photogramstart.domain.user.User;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public class UserProfileDto {
private boolean pageOwnerState;
private int imageCount;
private boolean subscribeState;
private int subscribeCount;
private User user;
}
구독자수를 알아보기위해서는 쿼리를 작성해봐야한다!
1번이 2번 구독한 상태에서 2번 페이지를 가게되면 이미 구독을 한상태이기 떄문에 구독취소인 상태로 보여야한다!
구독정보 또한 로그인 한사람의 구독정보가 아니라 2번 페이지 의 구독정보이기 떄문에 2번인 사람에 대한 몇명이 구독을 했는지 가 나와야한다!
-- 구 독 수
SELECT COUNT(*) FROM subscribe WHERE fromUserId = 3;
-- 구독 여부( ssar로 로그인, cos페이지로감
SELECT COUNT(*) FROM subscribe WHERE fromUserId = 1 AND toUserId = 2;
이 두가지 쿼리로 만들어볼수 있다!
SubscribeRepository에 가서
package com.cos.photogramstart.domain.subscribe;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
public interface SubscribeRepository extends JpaRepository<Subscribe, Integer> {
@Modifying // INSERT, DELETE, UPDATE를 네이티브 쿼리로 작성하려면 해당 어노테이션 필요!!
@Query(value = "INSERT INTO subscribe(fromUserId, toUserId, createDate) VALUES(:fromUserId, :toUserId, now())", nativeQuery = true)
void mSubscribe(int fromUserId, int toUserId);
@Modifying
@Query(value = "DELETE FROM subscribe WHERE fromUserId = :fromUserId AND toUserId = :toUserId", nativeQuery = true)
void mUnSubscribe(int fromUserId, int toUserId);
@Query(value ="SELECT COUNT(*) FROM subscribe WHERE fromUserId = :principalId AND toUserId = :pageUserId", nativeQuery = true)
int mSubscribeState(int principalId, int pageUserId);
@Query(value ="SELECt COUNT(*) FROM subscribe WHERE fromUserId = :pageUserId", nativeQuery = true)
int mSubscribeCount(int pageUserId);
}
principalId는 로그인한 아이디! , pageUserId: 그 페이지 아이디!
구독수는 그 페이지 아이디만 있으면된다!
이들을 실행하기 위해서는 유저컨트롤러에서 회원프로필로 갈때 저 정보를 같이 UserProfileDto에 담아갈것이기 때문에
회원프로필에서 UserService에서
package com.cos.photogramstart.service;
import java.util.function.Supplier;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.cos.photogramstart.domain.subscribe.SubscribeRepository;
import com.cos.photogramstart.domain.user.User;
import com.cos.photogramstart.domain.user.UserRepository;
import com.cos.photogramstart.handler.ex.CustomException;
import com.cos.photogramstart.handler.ex.CustomValidationApiException;
import com.cos.photogramstart.web.dto.user.UserProfileDto;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Service
public class UserService {
private final UserRepository userRepository;
private final SubscribeRepository subscribeRepository;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
@Transactional(readOnly = true)
public UserProfileDto 회원프로필(int pageUserId, int principalId) {
UserProfileDto dto = new UserProfileDto();
//SELECT * FROM image WHERE userId = :userId;
User userEntity = userRepository.findById(pageUserId).orElseThrow(()-> {
throw new CustomException("해당 프로필 페이지는 없는 페이지입니다.");
});
dto.setUser(userEntity);
dto.setPageOwnerState(pageUserId == principalId);
dto.setImageCount(userEntity.getImages().size());
int subscribeState = subscribeRepository.mSubscribeState(principalId, pageUserId);
int subscribeCount = subscribeRepository.mSubscribeCount(pageUserId);
dto.setSubscribeState(subscribeState == 1);
dto.setSubscribeCount(subscribeCount);
return dto;
}
@Transactional
public User 회원수정(int id, User user ) {
//1. 영속화
//1. 무조건 찾았다. 걱정마 get() 2. 못찾았어 익섹션 발통시킬때 orElseThrow()
User userEntity = userRepository.findById(id).orElseThrow(() -> {return new CustomValidationApiException("찾을 수 없는 id입니다."); });
//2. 영속화된 오브젝트를 수정 - 수정이 완료되면 더티체킹 ( 업데이트 완료)
userEntity.setName(user.getName());
String rawPassword = user.getPassword();
String encPassword = bCryptPasswordEncoder.encode(rawPassword);
userEntity.setPassword(encPassword);
userEntity.setBio(user.getBio());
userEntity.setWebsite(user.getWebsite());
userEntity.setPhone(user.getPhone());
userEntity.setGender(user.getGender());
return userEntity;
}//더티체킹이 일어나서 업데이트가 완료됨.
}
dto를 만드는것이 굉장히 효과적이다. 페이지에서 할것이 없고 페이지에서는 출력만 하면된다!
이제 profile.jsp로 가서
<li><a href="javascript:subscribeInfoModalOpen();"> 구독정보<span>${dto.subscribeCount }</span>
<c:choose>
<c:when test="${dto.pageOwnerState}">
<button class="cta" onclick="location.href='/image/upload'">사진등록</button>
</c:when>
<c:otherwise>
<c:choose>
<c:when test="${dto.subscribeState}" >
<button class="cta blue" onclick="toggleSubscribe(this)">구독취소</button>
</c:when>
<c:otherwise>
<button class="cta" onclick="toggleSubscribe(this)">구독하기</button>
</c:otherwise>
</c:choose>
</c:otherwise>
</c:choose>
cta가 붙으면 버튼 디자인만 붙은건데 blue라고 하면 파란색상이 나오는데 그것은 구독취소!
왜냐하면 구독 한상태의 페이지에갔을떄는 구독취소버튼만 보이면 되기떄문에!
'Back-End > Spring Boot' 카테고리의 다른 글
2/15 SpringBoot 구독 모달 정보 API 만들기! #3 (0) | 2022.02.15 |
---|---|
2/15 SpringBoot 구독 및 구독취소 구현하기 #2 (0) | 2022.02.15 |
2/14 SpringBoot Image 뷰 렌더링하기 (0) | 2022.02.14 |
2/14 SpringBoot Image DB에 업로드하기 (0) | 2022.02.14 |
SpringBoot 구독, 구독취소 API 만들기 (0) | 2022.02.14 |