From 2c58c65ab42d3de7a29b03613d1c252c90d461c8 Mon Sep 17 00:00:00 2001 From: mino Date: Tue, 18 Nov 2025 12:55:30 +0900 Subject: [PATCH 1/2] =?UTF-8?q?refactor=20:=20blogResponse=20=EC=9D=91?= =?UTF-8?q?=EB=8B=B5=20=EC=B6=94=EA=B0=80,=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/blog/dto/response/BlogResponse.java | 12 +++++++++--- .../blog/repository/BlogPostQueryRepositoryImpl.java | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/kusitms/website/domain/blog/dto/response/BlogResponse.java b/src/main/java/com/kusitms/website/domain/blog/dto/response/BlogResponse.java index fa5c722..887d779 100644 --- a/src/main/java/com/kusitms/website/domain/blog/dto/response/BlogResponse.java +++ b/src/main/java/com/kusitms/website/domain/blog/dto/response/BlogResponse.java @@ -19,23 +19,29 @@ public class BlogResponse { private Long id; @Schema(description = "블로그 글 제목") private String title; - @Schema(description = "블로그 카테고리 이름") - private Category category; @Schema(description = "블로그 주소") private String address; @Schema(description = "블로그 이미지 주소") private String imageAddress; @Schema(description = "블로그 글 내용") private String content; + @Schema(description = "활동명") + private String categoryName; + @Schema(description = "기수") + private Integer cardinal; + @Schema(description = "파트명") + private String position; public static BlogResponse fromEntity(BlogPost post) { return BlogResponse.builder() .id(post.getId()) .title(post.getTitle()) - .category(post.getCategory()) + .categoryName(post.getCategory().getDescription()) .address(post.getAddress()) .imageAddress(post.getImageAddress()) .content(post.getContent()) + .cardinal(post.getBlogAuthor().getGeneration()) + .position(post.getBlogAuthor().getPosition().getDescription()) .build(); } diff --git a/src/main/java/com/kusitms/website/domain/blog/repository/BlogPostQueryRepositoryImpl.java b/src/main/java/com/kusitms/website/domain/blog/repository/BlogPostQueryRepositoryImpl.java index 075d644..355a505 100644 --- a/src/main/java/com/kusitms/website/domain/blog/repository/BlogPostQueryRepositoryImpl.java +++ b/src/main/java/com/kusitms/website/domain/blog/repository/BlogPostQueryRepositoryImpl.java @@ -37,7 +37,7 @@ public List findByFiltersWithPaging(Integer generation, Position posit return queryFactory .selectFrom(blogPost) - .join(blogPost.blogAuthor, blogAuthor) + .join(blogPost.blogAuthor, blogAuthor).fetchJoin() .where(builder) .orderBy(blogPost.id.desc()) .limit(size) From 3300a54fcdbe0a1e5a8cf4f532644c71f0475312 Mon Sep 17 00:00:00 2001 From: mino Date: Tue, 18 Nov 2025 13:22:18 +0900 Subject: [PATCH 2/2] =?UTF-8?q?refactor=20:=20=EB=AC=B4=ED=95=9C=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A1=A4=20->=20=ED=8E=98=EC=9D=B4=EC=A7=95=20?= =?UTF-8?q?=EB=B0=A9=EC=8B=9D=EC=9C=BC=EB=A1=9C=EB=B3=80=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blog/controller/BlogController.java | 7 +-- .../blog/dto/response/BlogResponse.java | 32 ++++++----- .../repository/BlogPostQueryRepository.java | 6 ++- .../BlogPostQueryRepositoryImpl.java | 54 +++++++++++++++---- .../domain/blog/service/BlogService.java | 12 ++--- 5 files changed, 78 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/kusitms/website/domain/blog/controller/BlogController.java b/src/main/java/com/kusitms/website/domain/blog/controller/BlogController.java index e6237e5..fb56840 100644 --- a/src/main/java/com/kusitms/website/domain/blog/controller/BlogController.java +++ b/src/main/java/com/kusitms/website/domain/blog/controller/BlogController.java @@ -16,6 +16,8 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -44,10 +46,9 @@ public ResponseEntity getBlogList( @RequestParam(required = false) Integer generation, @RequestParam(required = false) Position position, @RequestParam(required = false) Category category, - @RequestParam(required = false) Long lastId, - @RequestParam(defaultValue = "10") int size + Pageable pageable ) { - List result = blogService.getFilteredPostsWithPaging(generation, position, category, lastId, size); + Page result = blogService.getFilteredPostsWithPaging(generation, position, category, pageable); return ResponseEntity.ok(new BaseResponse(result)); } } diff --git a/src/main/java/com/kusitms/website/domain/blog/dto/response/BlogResponse.java b/src/main/java/com/kusitms/website/domain/blog/dto/response/BlogResponse.java index 887d779..67fcd78 100644 --- a/src/main/java/com/kusitms/website/domain/blog/dto/response/BlogResponse.java +++ b/src/main/java/com/kusitms/website/domain/blog/dto/response/BlogResponse.java @@ -4,6 +4,7 @@ import com.kusitms.website.domain.blog.entity.BlogAuthor; import com.kusitms.website.domain.blog.entity.BlogPost; import com.kusitms.website.domain.blog.entity.Category; +import com.querydsl.core.annotations.QueryProjection; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; @@ -12,7 +13,6 @@ @Getter @Builder @NoArgsConstructor -@AllArgsConstructor public class BlogResponse { @JsonProperty("blog_post_id") @Schema(description = "블로그 글 아이디") @@ -32,18 +32,26 @@ public class BlogResponse { @Schema(description = "파트명") private String position; - public static BlogResponse fromEntity(BlogPost post) { - return BlogResponse.builder() - .id(post.getId()) - .title(post.getTitle()) - .categoryName(post.getCategory().getDescription()) - .address(post.getAddress()) - .imageAddress(post.getImageAddress()) - .content(post.getContent()) - .cardinal(post.getBlogAuthor().getGeneration()) - .position(post.getBlogAuthor().getPosition().getDescription()) - .build(); + @QueryProjection + public BlogResponse(Long id, + String title, + String address, + String imageAddress, + String content, + String categoryName, + Integer cardinal, + String position) { + this.id = id; + this.title = title; + this.address = address; + this.imageAddress = imageAddress; + this.content = content; + this.categoryName = categoryName; + this.cardinal = cardinal; + this.position = position; } + + } diff --git a/src/main/java/com/kusitms/website/domain/blog/repository/BlogPostQueryRepository.java b/src/main/java/com/kusitms/website/domain/blog/repository/BlogPostQueryRepository.java index 7829916..5f6b230 100644 --- a/src/main/java/com/kusitms/website/domain/blog/repository/BlogPostQueryRepository.java +++ b/src/main/java/com/kusitms/website/domain/blog/repository/BlogPostQueryRepository.java @@ -1,11 +1,13 @@ package com.kusitms.website.domain.blog.repository; +import com.kusitms.website.domain.blog.dto.response.BlogResponse; import com.kusitms.website.domain.blog.entity.BlogPost; import com.kusitms.website.domain.blog.entity.Category; import com.kusitms.website.domain.blog.entity.Position; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; -import java.util.List; public interface BlogPostQueryRepository { - List findByFiltersWithPaging(Integer generation, Position position, Category category, Long lastId, int size); + Page findByFiltersWithPaging(Integer generation, Position position, Category category, Pageable pageable); } diff --git a/src/main/java/com/kusitms/website/domain/blog/repository/BlogPostQueryRepositoryImpl.java b/src/main/java/com/kusitms/website/domain/blog/repository/BlogPostQueryRepositoryImpl.java index 355a505..a6c361f 100644 --- a/src/main/java/com/kusitms/website/domain/blog/repository/BlogPostQueryRepositoryImpl.java +++ b/src/main/java/com/kusitms/website/domain/blog/repository/BlogPostQueryRepositoryImpl.java @@ -1,9 +1,15 @@ package com.kusitms.website.domain.blog.repository; +import com.kusitms.website.domain.blog.dto.response.BlogResponse; import com.kusitms.website.domain.blog.entity.*; import com.querydsl.core.BooleanBuilder; +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.dsl.CaseBuilder; import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Repository; import java.util.List; @@ -15,7 +21,7 @@ public class BlogPostQueryRepositoryImpl implements BlogPostQueryRepository { private final QBlogAuthor blogAuthor = QBlogAuthor.blogAuthor; @Override - public List findByFiltersWithPaging(Integer generation, Position position, Category category, Long lastId, int size) { + public Page findByFiltersWithPaging(Integer generation, Position position, Category category, Pageable pageable) { BooleanBuilder builder = new BooleanBuilder(); @@ -31,16 +37,46 @@ public List findByFiltersWithPaging(Integer generation, Position posit builder.and(blogPost.category.eq(category)); } - if (lastId != null) { - builder.and(blogPost.id.lt(lastId)); - } - - return queryFactory - .selectFrom(blogPost) - .join(blogPost.blogAuthor, blogAuthor).fetchJoin() + List results = queryFactory + .select(Projections.constructor( + BlogResponse.class, + blogPost.id, + blogPost.title, + blogPost.address, + blogPost.imageAddress, + blogPost.content, + new CaseBuilder() + .when(blogPost.category.eq(Category.DOCUMENT)).then(Category.DOCUMENT.getDescription()) + .when(blogPost.category.eq(Category.INTERVIEW)).then(Category.INTERVIEW.getDescription()) + .when(blogPost.category.eq(Category.GIFT)).then(Category.GIFT.getDescription()) + .when(blogPost.category.eq(Category.MEETUP)).then(Category.MEETUP.getDescription()) + .when(blogPost.category.eq(Category.GROUP_TF)).then(Category.GROUP_TF.getDescription()) + .otherwise("기타"), + blogAuthor.generation, + // Position → description + new CaseBuilder() + .when(blogAuthor.position.eq(Position.FRONTEND)).then(Position.FRONTEND.getDescription()) + .when(blogAuthor.position.eq(Position.BACKEND)).then(Position.BACKEND.getDescription()) + .when(blogAuthor.position.eq(Position.PLAN)).then(Position.PLAN.getDescription()) + .when(blogAuthor.position.eq(Position.DESIGNER)).then(Position.DESIGNER.getDescription()) + .otherwise("기타") + )) + .from(blogPost) + .join(blogPost.blogAuthor, blogAuthor) .where(builder) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) .orderBy(blogPost.id.desc()) - .limit(size) .fetch(); + + // ② total count 조회 + long total = queryFactory + .select(blogPost.count()) + .from(blogPost) + .join(blogPost.blogAuthor, blogAuthor) + .where(builder) + .fetchOne(); + + return new PageImpl<>(results, pageable, total); } } diff --git a/src/main/java/com/kusitms/website/domain/blog/service/BlogService.java b/src/main/java/com/kusitms/website/domain/blog/service/BlogService.java index cba8365..38f43c1 100644 --- a/src/main/java/com/kusitms/website/domain/blog/service/BlogService.java +++ b/src/main/java/com/kusitms/website/domain/blog/service/BlogService.java @@ -7,6 +7,8 @@ import com.kusitms.website.domain.blog.repository.BlogPostQueryRepository; import com.kusitms.website.domain.blog.repository.BlogPostRepository; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import java.util.List; @@ -18,16 +20,12 @@ public class BlogService { private final BlogPostRepository blogPostRepository; - public List getFilteredPostsWithPaging( + public Page getFilteredPostsWithPaging( Integer generation, Position position, Category category, - Long lastId, - int size + Pageable pageable ) { - return blogPostRepository.findByFiltersWithPaging(generation, position, category, lastId, size) - .stream() - .map(BlogResponse::fromEntity) - .collect(Collectors.toList()); + return blogPostRepository.findByFiltersWithPaging(generation, position, category, pageable); } }