Skip to content

Commit

Permalink
β™» remove unnecessary JPQL (#457)
Browse files Browse the repository at this point in the history
  • Loading branch information
hyxrxn authored Mar 4, 2025
2 parents 764d594 + 96df263 commit 45cb6b0
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 124 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,6 @@ public record RecipeHomeWithMineResponseV1(
boolean mine
) {

public RecipeHomeWithMineResponseV1(
UserInfo userInfo,
RecipeHomeResponse firstResponse
) {
this(
firstResponse.recipeId(),
firstResponse.title(),
new AuthorResponse(firstResponse.authorId(), firstResponse.authorName(), firstResponse.authorImage()),
firstResponse.thumbnail(),
firstResponse.likeCount(),
firstResponse.commentCount(),
firstResponse.createdAt(),
userInfo.isSameUser(firstResponse.authorId())
);
}

public RecipeHomeWithMineResponseV1(
UserInfo userInfo,
Recipe recipe
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import jakarta.annotation.Nullable;
import java.util.List;
import net.pengcook.recipe.domain.Recipe;
import net.pengcook.recipe.dto.RecipeHomeResponse;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
Expand All @@ -12,26 +11,26 @@
public interface RecipeRepository extends JpaRepository<Recipe, Long> {

@Query("""
SELECT recipe.id
SELECT recipe
FROM CategoryRecipe
WHERE category.name = :category
ORDER BY recipe.createdAt DESC
""")
List<Long> findRecipeIdsByCategory(Pageable pageable, String category);
List<Recipe> findAllByCategory(Pageable pageable, String category);

@Query("""
SELECT id
FROM Recipe
WHERE title LIKE CONCAT('%', :keyword, '%')
OR description LIKE CONCAT('%', :keyword, '%')
ORDER BY createdAt DESC
SELECT r
FROM Recipe r
WHERE r.title LIKE CONCAT('%', :keyword, '%')
OR r.description LIKE CONCAT('%', :keyword, '%')
ORDER BY r.createdAt DESC
""")
List<Long> findRecipeIdsByKeyword(Pageable pageable, String keyword);
List<Recipe> findAllByKeyword(Pageable pageable, String keyword);

List<Recipe> findRecipeByAuthorIdOrderByCreatedAtDesc(Pageable pageable, long authorId);
List<Recipe> findAllByAuthorIdOrderByCreatedAtDesc(Pageable pageable, long authorId);

@Query("""
SELECT r.id
SELECT r
FROM Recipe r
LEFT JOIN CategoryRecipe cr ON cr.recipe = r
LEFT JOIN Category c ON cr.category = c
Expand All @@ -41,7 +40,7 @@ OR description LIKE CONCAT('%', :keyword, '%')
GROUP BY r.id, r.createdAt
ORDER BY r.createdAt DESC
""")
List<Long> findRecipeIdsByCategoryAndKeyword(
List<Recipe> findAllByCategoryAndKeyword(
Pageable pageable,
@Param("category") @Nullable String category,
@Param("keyword") @Nullable String keyword,
Expand All @@ -50,30 +49,7 @@ List<Long> findRecipeIdsByCategoryAndKeyword(

List<Recipe> findAllByIdInOrderByCreatedAtDesc(List<Long> recipeIds);

@Query("""
SELECT new net.pengcook.recipe.dto.RecipeHomeResponse(
r.id,
r.title,
r.author.id,
r.author.username,
r.author.image,
r.thumbnail,
r.likeCount,
r.commentCount,
r.createdAt
)
FROM Recipe r
WHERE r.id IN :recipeIds
ORDER BY r.createdAt DESC
""")
List<RecipeHomeResponse> findRecipeDataV1(List<Long> recipeIds);

@Query("""
SELECT r.id
FROM Recipe r
WHERE r.author.id = :userId
""")
List<Long> findRecipeIdsByUserId(long userId);
List<Recipe> findAllByAuthorId(long authorId);

List<Recipe> findAllByAuthorIdInOrderByCreatedAtDesc(List<Long> authorIds, Pageable pageable);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import net.pengcook.recipe.domain.Recipe;
import net.pengcook.recipe.dto.PageRecipeRequest;
import net.pengcook.recipe.dto.RecipeDescriptionResponse;
import net.pengcook.recipe.dto.RecipeHomeResponse;
import net.pengcook.recipe.dto.RecipeHomeWithMineResponse;
import net.pengcook.recipe.dto.RecipeHomeWithMineResponseV1;
import net.pengcook.recipe.dto.RecipeRequest;
Expand Down Expand Up @@ -60,27 +59,26 @@ public class RecipeService {
@Transactional(readOnly = true)
public List<RecipeHomeWithMineResponse> readRecipes(UserInfo userInfo, PageRecipeRequest pageRecipeRequest) {
Pageable pageable = pageRecipeRequest.getPageable();
List<Long> recipeIds = recipeRepository.findRecipeIdsByCategoryAndKeyword(
List<Recipe> recipes = recipeRepository.findAllByCategoryAndKeyword(
pageable,
pageRecipeRequest.category(),
pageRecipeRequest.keyword(),
pageRecipeRequest.userId()
);

return getRecipeHomeWithMineResponses(userInfo, recipeIds);
return getRecipeHomeWithMineResponses(userInfo, recipes);
}

@Transactional(readOnly = true)
public List<RecipeHomeWithMineResponseV1> readRecipesV1(UserInfo userInfo, PageRecipeRequest pageRecipeRequest) {
List<Long> recipeIds = findRecipeIdsByMultipleCondition(pageRecipeRequest);
List<RecipeHomeResponse> recipeHomeResponses = recipeRepository.findRecipeDataV1(recipeIds);
List<Recipe> recipes = findRecipesByMultipleCondition(pageRecipeRequest);

return recipeHomeResponses.stream()
.map(recipeHomeResponse -> new RecipeHomeWithMineResponseV1(userInfo, recipeHomeResponse))
return recipes.stream()
.map(recipe -> new RecipeHomeWithMineResponseV1(userInfo, recipe))
.toList();
}

private List<Long> findRecipeIdsByMultipleCondition(PageRecipeRequest pageRecipeRequest) {
private List<Recipe> findRecipesByMultipleCondition(PageRecipeRequest pageRecipeRequest) {
Pageable pageable = pageRecipeRequest.getPageable();
long conditionCount = pageRecipeRequest.getConditionCount();

Expand All @@ -90,38 +88,35 @@ private List<Long> findRecipeIdsByMultipleCondition(PageRecipeRequest pageRecipe
pageable.getPageSize(),
Sort.by(CREATION_DATE).descending()
);
return recipeRepository.findAll(descPageable).stream()
.map(Recipe::getId)
return recipeRepository.findAll(descPageable)
.toList();
}
if (conditionCount == 1) {
return findRecipeIdsBySingleCondition(pageRecipeRequest);
return findRecipesBySingleCondition(pageRecipeRequest);
}

return recipeRepository.findRecipeIdsByCategoryAndKeyword(
return recipeRepository.findAllByCategoryAndKeyword(
pageable,
pageRecipeRequest.category(),
pageRecipeRequest.keyword(),
pageRecipeRequest.userId()
);
}

private List<Long> findRecipeIdsBySingleCondition(PageRecipeRequest pageRecipeRequest) {
private List<Recipe> findRecipesBySingleCondition(PageRecipeRequest pageRecipeRequest) {
Pageable pageable = pageRecipeRequest.getPageable();
String category = pageRecipeRequest.category();
String keyword = pageRecipeRequest.keyword();
Long userId = pageRecipeRequest.userId();

if (category != null) {
return recipeRepository.findRecipeIdsByCategory(pageable, category);
return recipeRepository.findAllByCategory(pageable, category);
}
if (keyword != null) {
return recipeRepository.findRecipeIdsByKeyword(pageable, keyword);
return recipeRepository.findAllByKeyword(pageable, keyword);
}
if (userId != null) {
return recipeRepository.findRecipeByAuthorIdOrderByCreatedAtDesc(pageable, userId).stream()
.map(Recipe::getId)
.toList();
return recipeRepository.findAllByAuthorIdOrderByCreatedAtDesc(pageable, userId);
}
// TODO: need to throw illegal state
return List.of();
Expand All @@ -130,17 +125,18 @@ private List<Long> findRecipeIdsBySingleCondition(PageRecipeRequest pageRecipeRe
@Transactional(readOnly = true)
public List<RecipeHomeWithMineResponse> readLikeRecipes(UserInfo userInfo) {
List<Long> likeRecipeIds = likeRepository.findRecipeIdsByUserId(userInfo.getId());
List<Recipe> recipes = recipeRepository.findAllByIdInOrderByCreatedAtDesc(likeRecipeIds);

return getRecipeHomeWithMineResponses(userInfo, likeRecipeIds);
return getRecipeHomeWithMineResponses(userInfo, recipes);
}

@Transactional(readOnly = true)
public List<RecipeHomeWithMineResponseV1> readLikeRecipesV1(UserInfo userInfo) {
List<Long> likeRecipeIds = likeRepository.findRecipeIdsByUserId(userInfo.getId());
List<RecipeHomeResponse> recipeHomeResponses = recipeRepository.findRecipeDataV1(likeRecipeIds);
List<Recipe> recipes = recipeRepository.findAllByIdInOrderByCreatedAtDesc(likeRecipeIds);

return recipeHomeResponses.stream()
.map(recipeHomeResponse -> new RecipeHomeWithMineResponseV1(userInfo, recipeHomeResponse))
return recipes.stream()
.map(recipe -> new RecipeHomeWithMineResponseV1(userInfo, recipe))
.toList();
}

Expand Down Expand Up @@ -219,19 +215,21 @@ public RecipeDescriptionResponse readRecipeDescription(UserInfo userInfo, long r
public void deleteRecipe(UserInfo userInfo, long recipeId) {
Optional<Recipe> targetRecipe = recipeRepository.findById(recipeId);

targetRecipe.ifPresent(recipe -> {
verifyRecipeOwner(userInfo, recipe);
ingredientRecipeService.deleteIngredientRecipe(recipe.getId());
categoryService.deleteCategoryRecipe(recipe);
commentService.deleteCommentsByRecipe(recipe.getId());
recipeLikeService.deleteLikesByRecipe(recipe.getId());
recipeStepService.deleteRecipeStepsByRecipe(recipe.getId());
recipeRepository.delete(recipe);
});
targetRecipe.ifPresent(recipe -> deleteRecipe(userInfo, recipe));
}

@Transactional
public void deleteRecipe(UserInfo userInfo, Recipe recipe) {
verifyRecipeOwner(userInfo, recipe);
ingredientRecipeService.deleteIngredientRecipe(recipe.getId());
categoryService.deleteCategoryRecipe(recipe);
commentService.deleteCommentsByRecipe(recipe.getId());
recipeLikeService.deleteLikesByRecipe(recipe.getId());
recipeStepService.deleteRecipeStepsByRecipe(recipe.getId());
recipeRepository.delete(recipe);
}

private List<RecipeHomeWithMineResponse> getRecipeHomeWithMineResponses(UserInfo userInfo, List<Long> recipeIds) {
List<Recipe> recipes = recipeRepository.findAllByIdInOrderByCreatedAtDesc(recipeIds);
private List<RecipeHomeWithMineResponse> getRecipeHomeWithMineResponses(UserInfo userInfo, List<Recipe> recipes) {
return recipes.stream()
.map(recipe -> {
List<CategoryResponse> categories = categoryService.findCategoryByRecipe(recipe);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import net.pengcook.comment.repository.CommentRepository;
import net.pengcook.image.service.ImageClientService;
import net.pengcook.like.repository.RecipeLikeRepository;
import net.pengcook.recipe.domain.Recipe;
import net.pengcook.recipe.repository.RecipeRepository;
import net.pengcook.recipe.service.RecipeService;
import net.pengcook.user.domain.BlockeeGroup;
Expand Down Expand Up @@ -143,9 +144,9 @@ public void deleteUser(UserInfo userInfo) {
userReportRepository.deleteByReporterId(userInfo.getId());
userReportRepository.deleteByReporteeId(userInfo.getId());

List<Long> userRecipes = recipeRepository.findRecipeIdsByUserId(userInfo.getId());
for (Long recipeId : userRecipes) {
recipeService.deleteRecipe(userInfo, recipeId);
List<Recipe> userRecipes = recipeRepository.findAllByAuthorId(userInfo.getId());
for (Recipe recipe : userRecipes) {
recipeService.deleteRecipe(userInfo, recipe);
}
List<UserFollow> followings = userFollowRepository.findAllByFollowerId(userInfo.getId());
for (UserFollow userFollow : followings) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package net.pengcook.recipe.repository;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;

import java.time.LocalDateTime;
import java.util.List;
import net.pengcook.recipe.domain.Recipe;
import net.pengcook.recipe.dto.RecipeHomeResponse;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -23,64 +20,53 @@ class RecipeRepositoryTest {
private RecipeRepository repository;

@Test
@DisplayName("μš”μ²­ν•œ νŽ˜μ΄μ§€μ— μΉ΄ν…Œκ³ λ¦¬ μ΄λ¦„μœΌλ‘œ λ ˆμ‹œν”Ό id λͺ©λ‘μ„ λ°˜ν™˜ν•œλ‹€.")
void findRecipeIdsByCategory() {
// given
@DisplayName("μš”μ²­ν•œ νŽ˜μ΄μ§€μ— μΉ΄ν…Œκ³ λ¦¬ μ΄λ¦„μœΌλ‘œ λ ˆμ‹œν”Ό λͺ©λ‘μ„ λ°˜ν™˜ν•œλ‹€.")
void findRecipesByCategory() {
Pageable pageable = PageRequest.of(0, 3);
String category = "ν•œμ‹";

// when
List<Long> recipeIds = repository.findRecipeIdsByCategory(pageable, category);
List<Recipe> recipes = repository.findAllByCategory(pageable, category);
List<Long> recipeIds = recipes.stream()
.map(Recipe::getId)
.toList();

// then
assertThat(recipeIds).contains(15L, 14L, 9L);
}

@Test
@DisplayName("μš”μ²­ν•œ νŽ˜μ΄μ§€μ— ν‚€μ›Œλ“œλ‘œ λ ˆμ‹œν”Ό id λͺ©λ‘μ„ λ°˜ν™˜ν•œλ‹€.")
void findRecipeIdsByKeyword() {
// given
@DisplayName("μš”μ²­ν•œ νŽ˜μ΄μ§€μ— ν‚€μ›Œλ“œλ‘œ λ ˆμ‹œν”Ό λͺ©λ‘μ„ λ°˜ν™˜ν•œλ‹€.")
void findRecipesByKeyword() {
Pageable pageable = PageRequest.of(0, 3);
String keyword = "이크";

// when
List<Long> recipeIds = repository.findRecipeIdsByKeyword(pageable, keyword);
List<Recipe> recipes = repository.findAllByKeyword(pageable, keyword);
List<Long> recipeIds = recipes.stream()
.map(Recipe::getId)
.toList();

// then
assertThat(recipeIds).containsExactly(12L, 11L);
}

@Test
@DisplayName("μš”μ²­ν•œ νŽ˜μ΄μ§€μ— ν•΄λ‹Ήν•˜λŠ” λ ˆμ‹œν”Ό id λͺ©λ‘μ„ λ°˜ν™˜ν•œλ‹€.")
void findRecipeIdsByCategoryAndKeyword() {
@DisplayName("μš”μ²­ν•œ νŽ˜μ΄μ§€μ— ν•΄λ‹Ήν•˜λŠ” λ ˆμ‹œν”Ό λͺ©λ‘μ„ λ°˜ν™˜ν•œλ‹€.")
void findRecipesByCategoryAndKeyword() {
Pageable pageable = PageRequest.of(0, 3);

List<Long> recipeIds = repository.findRecipeIdsByCategoryAndKeyword(pageable, null, null, null);
List<Recipe> recipes = repository.findAllByCategoryAndKeyword(pageable, null, null, null);
List<Long> recipeIds = recipes.stream()
.map(Recipe::getId)
.toList();

assertThat(recipeIds).containsExactly(15L, 14L, 13L);
}

@Test
@DisplayName("λ ˆμ‹œν”Ό id에 ν•΄λ‹Ήλ˜λŠ” μ„ΈλΆ€ 정보λ₯Ό λ°˜ν™˜ν•œλ‹€.")
void findRecipeData() {
List<Long> recipeIds = List.of(4L, 3L);
RecipeHomeResponse expectedData = new RecipeHomeResponse(4, "ν† λ§ˆν† μŠ€νŒŒκ²Œν‹°", 1, "loki", "loki.jpg",
"ν† λ§ˆν† μŠ€νŒŒκ²Œν‹°μ΄λ―Έμ§€.jpg", 2, 0, LocalDateTime.of(2024, 7, 2, 13, 0, 0));

List<RecipeHomeResponse> recipeData = repository.findRecipeDataV1(recipeIds);

assertAll(
() -> assertThat(recipeData).hasSize(2),
() -> assertThat(recipeData).contains(expectedData)
);
}

@Test
@DisplayName("μ‚¬μš©μž id둜 μž‘μ„±λœ λ ˆμ‹œν”Ό id λͺ©λ‘μ„ μ΅œμ‹  순으둜 λ°˜ν™˜ν•œλ‹€.")
void findRecipeIdsByUserId() {
@DisplayName("μ‚¬μš©μž id둜 μž‘μ„±λœ λ ˆμ‹œν”Ό λͺ©λ‘μ„ μ΅œμ‹  순으둜 λ°˜ν™˜ν•œλ‹€.")
void findRecipesByUserId() {
Pageable pageable = PageRequest.of(0, 3);

List<Long> recipeIds = repository.findRecipeByAuthorIdOrderByCreatedAtDesc(pageable, 1L).stream()
List<Recipe> recipes = repository.findAllByAuthorIdOrderByCreatedAtDesc(pageable, 1L);
List<Long> recipeIds = recipes.stream()
.map(Recipe::getId)
.toList();

Expand Down

0 comments on commit 45cb6b0

Please sign in to comment.