패스트캠퍼스
패스트캠퍼스 환급챌린지 33일차 : 9개 도메인 프로젝트로 끝내는 백엔드 웹 개발 (Java/Spring) 초격차 패키지 Online 강의 후기
이태우(1990년)
2025. 4. 6. 23:25
본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다.
공부 시작 시각 인증

수강 인증 사진

※ 피드 테스트 결과, 피드 관련 소스들에서 잘못 코딩된 부분 수정하여 고침...
UserPostQueueEntity.java
package org.fastcampus.post.repository.entity.post;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Entity
@Table(name = "community_user_post_queue")
@NoArgsConstructor
@AllArgsConstructor
@Getter
public class UserPostQueueEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long userId;
private Long postId;
private Long authorId;
public UserPostQueueEntity(Long postId, Long userId, Long authorId) {
this.postId = postId;
this.userId = userId;
this.authorId = authorId;
}
}
JpaUserPostQueueRepository.java
package org.fastcampus.post.repository.jpa;
import org.fastcampus.post.repository.entity.post.UserPostQueueEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface JpaUserPostQueueRepository extends JpaRepository<UserPostQueueEntity, Long> {
void deleteAllByUserIdAndAuthorId(Long userId, Long authorId);
}
JpaPostRepository.java
package org.fastcampus.post.repository.jpa;
import java.util.List;
import org.fastcampus.post.repository.entity.post.*;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
public interface JpaPostRepository extends JpaRepository<PostEntity, Long> {
@Query("SELECT p.id FROM PostEntity p WHERE p.author.id = :authorId")
List<Long> findAllPostIdsByAuthorId(Long authorId);
@Modifying
@Query(value = "UPDATE PostEntity p"
+ " SET p.content = :#{#post.getContent()},"
+ " p.state = :#{#post.getState()},"
+ " p.updDt = now()"
+ " WHERE p.id = :#{#post.id}")
void updatePostEntity(PostEntity post);
@Modifying
@Query(value = "UPDATE PostEntity p"
+ " SET p.likeCount = p.likeCount + :likeCount,"
+ " p.updDt = now()"
+ " WHERE p.id = :postId")
void updatePostLikeCount(Long postId, Integer likeCount);
@Modifying
@Query(value ="UPDATE PostEntity p"
+ " SET p.commentCount = p.commentCount + 1,"
+ " p.updDt = now()"
+ " WHERE p.id = :id")
void increaseCommentCount(Long id);
}
UserPostQueueCommandRepositoryImpl.java
package org.fastcampus.post.repository.post_queue;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.fastcampus.post.repository.entity.post.PostEntity;
import org.fastcampus.post.repository.entity.post.UserPostQueueEntity;
import org.fastcampus.post.repository.jpa.JpaPostRepository;
import org.fastcampus.post.repository.jpa.JpaUserPostQueueRepository;
import org.fastcampus.user.repository.entity.UserEntity;
import org.fastcampus.user.repository.jpa.JpaUserRelationRepository;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class UserPostQueueCommandRepositoryImpl implements UserPostQueueCommandRepository {
private final JpaPostRepository jpaPostRepository;
private final JpaUserRelationRepository jpaUserRelationRepository;
private final JpaUserPostQueueRepository jpaUserPostQueueRepository;
public void publishPost(PostEntity postEntity) {
UserEntity authorEntity = postEntity.getAuthor();
List<Long> followers = jpaUserRelationRepository.findFollowers(authorEntity.getId());
List<UserPostQueueEntity> userPostQueueEntities = followers.stream()
.map(userId -> new UserPostQueueEntity(postEntity.getId(), userId, authorEntity.getId()))
.toList();
jpaUserPostQueueRepository.saveAll(userPostQueueEntities);
}
public void saveFollowPost(Long userId, Long targetId) {
List<Long> postIds = jpaPostRepository.findAllPostIdsByAuthorId(targetId);
List<UserPostQueueEntity> userPostQueueEntities = postIds.stream()
.map(postId -> new UserPostQueueEntity(postId, userId, targetId))
.toList();
jpaUserPostQueueRepository.saveAll(userPostQueueEntities);
}
public void deleteUnfollowPost(Long userId, Long targetId) {
jpaUserPostQueueRepository.deleteAllByUserIdAndAuthorId(userId, targetId);
}
}
GetContentResponseDto.java
package org.fastcampus.post.application.dto;
import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
@Getter
@Setter
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class GetContentResponseDto {
private Long id;
private String content;
private Long userId;
private String userName;
private String userProfileUrl;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
private Integer likeCount;
private boolean isLikedByMe;
}
※ GetPostContentResponseDto.java 클래스도 함께 이동 됨!
UserPostQueueQueryRepositoryImpl.java
package org.fastcampus.post.repository.post_queue;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.fastcampus.post.application.dto.GetPostContentResponseDto;
import org.fastcampus.post.repository.entity.like.QLikeEntity;
import org.fastcampus.post.repository.entity.post.QPostEntity;
import org.fastcampus.post.repository.entity.post.QUserPostQueueEntity;
import org.fastcampus.user.repository.entity.QUserEntity;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class UserPostQueueQueryRepositoryImpl {
private final JPAQueryFactory queryFactory;
private static final QUserPostQueueEntity userPostQueueEntity = QUserPostQueueEntity.userPostQueueEntity;
private static final QPostEntity postEntity = QPostEntity.postEntity;
private static final QUserEntity userEntity = QUserEntity.userEntity;
private static final QLikeEntity likeEntity = QLikeEntity.likeEntity;
public List<GetPostContentResponseDto> getContentResponse(Long userId, Long lastContentId) {
return queryFactory
.select(
Projections.fields(
GetPostContentResponseDto.class,
postEntity.id.as("id"),
postEntity.content.as("content"),
userEntity.id.as("userId"),
userEntity.name.as("userName"),
userEntity.profileUrl.as("userProfileUrl"),
postEntity.regDt.as("createdAt"),
postEntity.updDt.as("updatedAt"),
postEntity.commentCount.as("commentCount"),
postEntity.likeCount.as("likeCount"),
likeEntity.isNotNull().as("isLikedByMe")
)
)
.from(userPostQueueEntity)
.join(postEntity).on(userPostQueueEntity.postId.eq(postEntity.id))
.join(userEntity).on(userPostQueueEntity.authorId.eq(userEntity.id))
.leftJoin(likeEntity).on(hasLike(userId))
.where(
userPostQueueEntity.userId.eq(userId),
hasLastData(lastContentId)
)
.orderBy(userPostQueueEntity.postId.desc())
.limit(20)
.fetch();
}
private BooleanExpression hasLike(Long userId) {
if (userId == null) {
return null;
}
return postEntity.id
.eq(likeEntity.id.targetId)
.and(likeEntity.id.targetType.eq("POST"))
.and(likeEntity.id.userId.eq(userId));
}
private BooleanExpression hasLastData(Long lastContentId) {
if (lastContentId == null) {
return null;
}
return postEntity.id.lt(lastContentId);
}
}
※ UserPostQueueQueryRepository 자바 인터페이스는 삭제됨!
FeedController.java
package org.fastcampus.post.ui;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.fastcampus.common.ui.*;
import org.fastcampus.post.application.dto.GetPostContentResponseDto;
import org.fastcampus.post.repository.post_queue.UserPostQueueQueryRepositoryImpl;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/feed")
@RequiredArgsConstructor
public class FeedController {
private final UserPostQueueQueryRepositoryImpl userPostQueueQueryRepository;
@GetMapping("/{userId}")
public Response<List<GetPostContentResponseDto>> getPostFeedList(@PathVariable(name = "userId") Long userId, Long lastContentId) {
List<GetPostContentResponseDto> contentResponse = userPostQueueQueryRepository.getContentResponse(userId, lastContentId);
return Response.OK(contentResponse);
}
}
학습 인증샷

공부 종료 시각 인증
