Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking โ€œSign up for GitHubโ€, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

๐Ÿ”ง ํ”„๋ก ํŠธ ์ธก ์š”๊ตฌ์‚ฌํ•ญ ๋ฐ ์ผ๋ถ€ ๋ฒ„๊ทธ ํ”ฝ์Šค #98

Merged
merged 4 commits into from
Feb 4, 2024
Next Next commit
fix: #96 memoImage ๋นˆ ๋ฌธ์ž์—ด ๋ฐ˜ํ™˜ && memoInfo ๋ฐ˜ํ™˜ ์‹œ summary dto ๋ถ„๋ฆฌ (image nuโ€ฆ
โ€ฆll handling ๊ณ ๋ฏผ ํ•„์š”)
psychology50 committed Feb 2, 2024
commit 829b6e8a8453aa173872f24d511c10d16c67c23c
Original file line number Diff line number Diff line change
@@ -9,6 +9,6 @@

public interface MemoQueryDslRepository {
Optional<MemoInfoDto.MemoInfo> findMemoAndMemoImageUrlsById(Long memoId);
Slice<MemoInfoDto.MemoInfo> findMemosInMemoCategory(Long memoCategoryId, Pageable pageable, String target);
Slice<MemoInfoDto.MemoInfo> findMemosByPetId(Long petId, Pageable pageable);
Slice<MemoInfoDto.MemoSummaryInfo> findMemosInMemoCategory(Long memoCategoryId, Pageable pageable, String target);
Slice<MemoInfoDto.MemoSummaryInfo> findMemosByPetId(Long petId, Pageable pageable);
}
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
import com.kcy.fitapet.global.common.util.querydsl.QueryDslUtil;
import com.kcy.fitapet.global.common.util.querydsl.RepositorySliceHelper;
import com.querydsl.core.ResultTransformer;
import com.querydsl.core.group.GroupBy;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions;
@@ -40,8 +41,8 @@ public Optional<MemoInfoDto.MemoInfo> findMemoAndMemoImageUrlsById(Long memoId)
MemoInfoDto.MemoInfo.class,
memo.id,
memoCategory.categoryName,
QueryDslUtil.left(memo.title, Expressions.constant(19)),
QueryDslUtil.left(memo.content, Expressions.constant(16)),
memo.title,
memo.content,
memo.createdAt,
list(
Projections.constructor(
@@ -81,8 +82,8 @@ public Optional<MemoInfoDto.MemoInfo> findMemoAndMemoImageUrlsById(Long memoId)
* </pre>
*/
@Override
public Slice<MemoInfoDto.MemoInfo> findMemosInMemoCategory(Long memoCategoryId, Pageable pageable, String target) {
List<MemoInfoDto.MemoInfo> results = queryFactory
public Slice<MemoInfoDto.MemoSummaryInfo> findMemosInMemoCategory(Long memoCategoryId, Pageable pageable, String target) {
List<MemoInfoDto.MemoSummaryInfo> results = queryFactory
.from(memo)
.leftJoin(memoImage).on(memoImage.memo.id.eq(memo.id))
.where(memo.id.in(
@@ -104,8 +105,8 @@ public Slice<MemoInfoDto.MemoInfo> findMemosInMemoCategory(Long memoCategoryId,
}

@Override
public Slice<MemoInfoDto.MemoInfo> findMemosByPetId(Long petId, Pageable pageable) {
List<MemoInfoDto.MemoInfo> results = queryFactory
public Slice<MemoInfoDto.MemoSummaryInfo> findMemosByPetId(Long petId, Pageable pageable) {
List<MemoInfoDto.MemoSummaryInfo> results = queryFactory
.from(memoCategory)
.leftJoin(memo).on(memo.memoCategory.id.eq(memoCategory.id))
.leftJoin(memoImage).on(memoImage.memo.id.eq(memo.id))
@@ -125,21 +126,19 @@ public Slice<MemoInfoDto.MemoInfo> findMemosByPetId(Long petId, Pageable pageabl
return RepositorySliceHelper.toSlice(results, pageable);
}

private ResultTransformer<List<MemoInfoDto.MemoInfo>> createMemoInfoDtoResultTransformer() {
private ResultTransformer<List<MemoInfoDto.MemoSummaryInfo>> createMemoInfoDtoResultTransformer() {
return groupBy(memo.id).list(
Projections.constructor(
MemoInfoDto.MemoInfo.class,
MemoInfoDto.MemoSummaryInfo.class,
memo.id,
queryFactory.select(memoCategory.categoryName).from(memoCategory).where(memoCategory.id.eq(memo.memoCategory.id)),
QueryDslUtil.left(memo.title, Expressions.constant(19)),
QueryDslUtil.left(memo.content, Expressions.constant(16)),
memo.createdAt,
list(
Projections.constructor(
MemoInfoDto.MemoImageInfo.class,
memoImage.id,
memoImage.imgUrl
).skipNulls()
Projections.constructor( // TODO: 2024-02-02 : memoImage ๊ฒฐ๊ณผ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ผ ๋•Œ, ์–ด๋–ค ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š”์ง€? LIMIT์„ ๋ฐ–์œผ๋กœ ๋นผ๋„ ๋˜๋Š”์ง€?
MemoInfoDto.MemoImageInfo.class,
memoImage.id,
memoImage.imgUrl
).skipNulls()
)
);
34 changes: 29 additions & 5 deletions src/main/java/com/kcy/fitapet/domain/memo/dto/MemoInfoDto.java
Original file line number Diff line number Diff line change
@@ -11,9 +11,11 @@
import lombok.Getter;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Slice;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

@Getter
public class MemoInfoDto {
@@ -42,31 +44,53 @@ public record MemoInfo(
public MemoInfo(Long memoId, String categorySuffix, String title, String content, LocalDateTime createdAt, List<MemoImageInfo> memoImages) {
this.memoId = memoId;
this.categorySuffix = categorySuffix;
this.title = title.length() == 19 ? title + "..." : title;
this.content = content.length() == 16 ? content + "..." : content;
this.title = title;
this.content = content;
this.createdAt = createdAt;
this.memoImages = (memoImages == null) ? List.of() : memoImages;
}
}

@Builder
@Dto(name = "memo")
public record MemoSummaryInfo(
Long memoId,
String categorySuffix,
String title,
String content,
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
LocalDateTime createdAt,
MemoImageInfo memoImage
) {
public MemoSummaryInfo(Long memoId, String categorySuffix, String title, String content, LocalDateTime createdAt, MemoImageInfo memoImage) {
this.memoId = memoId;
this.categorySuffix = categorySuffix;
this.title = title.length() == 19 ? title + "..." : title;
this.content = content.length() == 16 ? content.replace("\n", " ") + "..." : content.replace("\n", " ");
this.createdAt = createdAt;
this.memoImage = memoImage;
}
}

public record MemoImageInfo(
Long memoImageId,
String imgUrl
) {
public MemoImageInfo(Long memoImageId, String imgUrl) {
this.memoImageId = memoImageId;
this.imgUrl = imgUrl;
this.imgUrl = Objects.toString(imgUrl, "");
}
}

public record PageResponse(
@Schema(description = "๋ฉ”๋ชจ ๋ชฉ๋ก") List<MemoInfo> memos,
@Schema(description = "๋ฉ”๋ชจ ๋ชฉ๋ก") List<?> memos,
@Schema(description = "ํ˜„์žฌ ํŽ˜์ด์ง€") int currentPageNumber,
@Schema(description = "ํŽ˜์ด์ง€ ํฌ๊ธฐ") int pageSize,
@Schema(description = "ํ˜„์žฌ ํŽ˜์ด์ง€์˜ ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜") int numberOfElements,
@Schema(description = "๋‹ค์Œ ํŽ˜์ด์ง€ ์กด์žฌ ์—ฌ๋ถ€") boolean hasNext
) {
public static PageResponse from(@NotNull Slice<MemoInfo> page) {
public static PageResponse from(@NotNull Slice<?> page) {
return new PageResponse(page.getContent(), page.getPageable().getPageNumber(), page.getPageable().getPageSize(), page.getNumberOfElements(), page.hasNext());
}
}
Original file line number Diff line number Diff line change
@@ -76,14 +76,14 @@ public MemoInfoDto.MemoInfo findMemoAndMemoImageUrlsById(Long memoId) {

@Transactional(readOnly = true)
public MemoInfoDto.PageResponse findMemosInMemoCategory(Long memoCategoryId, Pageable pageable, String target) {
Slice<MemoInfoDto.MemoInfo> page = memoRepository.findMemosInMemoCategory(memoCategoryId, pageable, target);
Slice<MemoInfoDto.MemoSummaryInfo> page = memoRepository.findMemosInMemoCategory(memoCategoryId, pageable, target);

return MemoInfoDto.PageResponse.from(page);
}

@Transactional(readOnly = true)
public MemoInfoDto.PageResponse findMemosByPetId(Long petId, Pageable pageable) {
Slice<MemoInfoDto.MemoInfo> page = memoRepository.findMemosByPetId(petId, pageable);
Slice<MemoInfoDto.MemoSummaryInfo> page = memoRepository.findMemosByPetId(petId, pageable);

return MemoInfoDto.PageResponse.from(page);
}
Original file line number Diff line number Diff line change
@@ -7,6 +7,12 @@
import java.util.List;

public class RepositorySliceHelper {
/**
* List๋กœ ๋ฐ›์€ contents๋ฅผ Slice๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.
* @param contents : ๋ณ€ํ™˜ํ•  List
* @param pageable : Pageable
* @return Slice<T> : ๋ณ€ํ™˜๋œ Slice. ๋‹จ, contents.size()๊ฐ€ pageable.getPageSize()๋ณด๋‹ค ์ž‘์„ ๊ฒฝ์šฐ hasNext๋Š” true์ด๋ฉฐ, Slice์˜ size๋Š” contents.size() - 1์ด๋‹ค.
*/
public static <T> Slice<T> toSlice(List<T> contents, Pageable pageable) {
boolean hasNext = isContentSizeGreaterThanPageSize(contents, pageable);
return new SliceImpl<>(hasNext ? subListLastContent(contents, pageable) : contents, pageable, hasNext);
@@ -16,7 +22,6 @@ private static <T> boolean isContentSizeGreaterThanPageSize(List<T> content, Pag
return pageable.isPaged() && content.size() > pageable.getPageSize();
}

// ๋ฐ์ดํ„ฐ 1๊ฐœ ๋นผ๊ณ  ๋ฐ˜ํ™˜
private static <T> List<T> subListLastContent(List<T> content, Pageable pageable) {
return content.subList(0, pageable.getPageSize());
}