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

기존 분기처리된 쿼리를 Specification를 사용하여 변경 #531

Merged
merged 6 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ public interface SpringDocTemplateController {
ResponseEntity<Void> createTemplate(MemberDto memberDto, CreateTemplateRequest createTemplateRequest);

@SecurityRequirement(name = "쿠키 인증 토큰")
@Operation(summary = "템플릿 검색", description = """
필터링 조건에 맞는 모든 템플릿을 조회합니다. \n
- 필터링 조건 \n
@Operation(summary = "템플릿 조회", description = """
조건에 맞는 모든 템플릿을 조회합니다. \n
- 조건 \n
- 멤버 ID
- 검색 키워드 (템플릿명, 템플릿 설명, 파일명, 소스 코드)
- 카테고리 ID
Expand Down Expand Up @@ -87,7 +87,6 @@ public interface SpringDocTemplateController {
@ErrorCase(description = "태그가 없는 경우", exampleMessage = "식별자 1에 해당하는 태그가 존재하지 않습니다."),
})
ResponseEntity<FindAllTemplatesResponse> getTemplates(
MemberDto memberDto,
Long memberId,
String keyword,
Long categoryId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@
import codezap.member.dto.MemberDto;
import codezap.template.dto.request.CreateTemplateRequest;
import codezap.template.dto.request.UpdateTemplateRequest;
import codezap.template.dto.response.ExploreTemplatesResponse;
import codezap.template.dto.response.FindAllTemplatesResponse;
import codezap.template.dto.response.FindTemplateResponse;
import codezap.template.service.ThumbnailService;
import codezap.template.service.facade.MemberTemplateApplicationService;
import codezap.template.service.facade.TemplateApplicationService;
import lombok.RequiredArgsConstructor;

@RestController
Expand All @@ -34,7 +33,7 @@
public class TemplateController implements SpringDocTemplateController {

private final MemberTemplateApplicationService memberTemplateApplicationService;
private final ThumbnailService thumbnailService;
private final TemplateApplicationService templateApplicationService;

@PostMapping
public ResponseEntity<Void> createTemplate(
Expand All @@ -48,15 +47,14 @@ public ResponseEntity<Void> createTemplate(

@GetMapping
public ResponseEntity<FindAllTemplatesResponse> getTemplates(
@AuthenticationPrinciple MemberDto memberDto,
@RequestParam Long memberId,
@RequestParam String keyword,
@RequestParam(required = false) Long memberId,
@RequestParam(required = false) String keyword,
@RequestParam(required = false) Long categoryId,
@RequestParam(required = false) List<Long> tagIds,
@PageableDefault(size = 20, page = 1) Pageable pageable
) {
FindAllTemplatesResponse response =
memberTemplateApplicationService.findAllBy(memberDto, memberId, keyword, categoryId, tagIds, pageable);
FindAllTemplatesResponse response = templateApplicationService.findAllBy(
memberId, keyword, categoryId, tagIds, pageable);
return ResponseEntity.ok(response);
}

Expand All @@ -68,11 +66,6 @@ public ResponseEntity<FindTemplateResponse> getTemplateById(
return ResponseEntity.ok(memberTemplateApplicationService.getByIdAndMember(memberDto, id));
}

@GetMapping("/explore")
public ResponseEntity<ExploreTemplatesResponse> explore() {
return ResponseEntity.ok(thumbnailService.findAll());
}

@PostMapping("/{id}")
public ResponseEntity<Void> updateTemplate(
@AuthenticationPrinciple MemberDto memberDto,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.http.HttpStatus;

import codezap.global.exception.CodeZapException;
Expand All @@ -27,81 +25,5 @@ default Template fetchById(Long id) {

Page<Template> findAll(Specification<Template> specification, Pageable pageable);

@Query("""
SELECT DISTINCT t
FROM Template t JOIN SourceCode s ON t.id = s.template.id
WHERE t.member.id = :memberId AND
(
t.title LIKE :keyword
OR s.filename LIKE :keyword
OR s.content LIKE :keyword
OR t.description LIKE :keyword
)
""")
Page<Template> searchBy(
@Param("memberId") Long memberId,
@Param("keyword") String keyword,
Pageable pageable
);

@Query("""
SELECT DISTINCT t
FROM Template t JOIN SourceCode s ON t.id = s.template.id
WHERE t.member.id = :memberId AND
t.id in :templateIds AND
(
t.title LIKE :keyword
OR s.filename LIKE :keyword
OR s.content LIKE :keyword
OR t.description LIKE :keyword
)
""")
Page<Template> searchBy(
@Param("memberId") Long memberId,
@Param("keyword") String keyword,
@Param("templateIds") List<Long> templateIds,
Pageable pageable
);

@Query("""
SELECT DISTINCT t
FROM Template t JOIN SourceCode s ON t.id = s.template.id
WHERE t.member.id = :memberId AND
t.category.id = :categoryId AND
(
t.title LIKE :keyword
OR s.filename LIKE :keyword
OR s.content LIKE :keyword
OR t.description LIKE :keyword
)
""")
Page<Template> searchBy(
@Param("memberId") Long memberId,
@Param("keyword") String keyword,
@Param("categoryId") Long categoryId,
Pageable pageable
);

@Query("""
SELECT DISTINCT t
FROM Template t JOIN SourceCode s ON t.id = s.template.id
WHERE t.member.id = :memberId AND
t.category.id = :categoryId AND
t.id in :templateIds AND
(
t.title LIKE :keyword
OR s.filename LIKE :keyword
OR s.content LIKE :keyword
OR t.description LIKE :keyword
)
""")
Page<Template> searchBy(
@Param("memberId") Long memberId,
@Param("keyword") String keyword,
@Param("categoryId") Long categoryId,
@Param("templateIds") List<Long> templateIds,
Pageable pageable
);

boolean existsByCategoryId(Long categoryId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,6 @@ public interface TemplateRepository {

Page<Template> findAll(Specification<Template> specification, Pageable pageable);

Page<Template> searchBy(Long memberId, String keyword, Pageable pageable);

Page<Template> searchBy(Long memberId, String keyword, List<Long> templateIds, Pageable pageable);

Page<Template> searchBy(Long memberId, String keyword, Long categoryId, Pageable pageable);

Page<Template> searchBy(Long memberId, String keyword, Long categoryId, List<Long> templateIds, Pageable pageable);

boolean existsByCategoryId(Long categoryId);

Template save(Template template);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import org.springframework.data.jpa.domain.Specification;

import codezap.template.domain.SourceCode;
import codezap.template.domain.Template;
import codezap.template.domain.TemplateTag;

Expand All @@ -20,27 +21,21 @@ public class TemplateSpecification implements Specification<Template> {
private final Long categoryId;
private final List<Long> tagIds;

private TemplateSpecification(Long memberId, String keyword, Long categoryId, List<Long> tagIds) {
public TemplateSpecification(Long memberId, String keyword, Long categoryId, List<Long> tagIds) {
this.memberId = memberId;
this.keyword = keyword;
this.categoryId = categoryId;
this.tagIds = tagIds;
}

public static Specification<Template> withDynamicQuery(
Long memberId, String keyword, Long categoryId, List<Long> tagIds
) {
return new TemplateSpecification(memberId, keyword, categoryId, tagIds);
}

@Override
public Predicate toPredicate(Root<Template> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicates = new ArrayList<>();

addMemberPredicate(predicates, criteriaBuilder, root);
addCategoryPredicate(predicates, criteriaBuilder, root);
addTagPredicate(predicates, criteriaBuilder, root, query);
addKeywordPredicate(predicates, criteriaBuilder, root);
addKeywordPredicate(predicates, criteriaBuilder, root, query);

return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
}
Expand All @@ -51,11 +46,22 @@ private void addMemberPredicate(List<Predicate> predicates, CriteriaBuilder crit
}
}

private void addKeywordPredicate(List<Predicate> predicates, CriteriaBuilder criteriaBuilder, Root<Template> root) {
private void addKeywordPredicate(List<Predicate> predicates, CriteriaBuilder criteriaBuilder, Root<Template> root,
CriteriaQuery<?> query
) {
Comment on lines +49 to +51
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private void addKeywordPredicate(List<Predicate> predicates, CriteriaBuilder criteriaBuilder, Root<Template> root,
CriteriaQuery<?> query
) {
private void addKeywordPredicate(
List<Predicate> predicates,
CriteriaBuilder criteriaBuilder,
Root<Template> root,
CriteriaQuery<?> query
) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#532 pr에서 반영하겠습니다!

if (keyword != null && !keyword.trim().isEmpty()) {
String likeKeyword = "%" + keyword.trim() + "%";
predicates.add(criteriaBuilder.or(criteriaBuilder.like(root.get("title"), likeKeyword),
criteriaBuilder.like(root.get("description"), likeKeyword)));
Predicate titlePredicate = criteriaBuilder.like(root.get("title"), likeKeyword);
Predicate descriptionPredicate = criteriaBuilder.like(root.get("description"), likeKeyword);

Subquery<Long> sourceCodeSubquery = query.subquery(Long.class);
Root<SourceCode> sourceCodeRoot = sourceCodeSubquery.from(SourceCode.class);
sourceCodeSubquery.select(sourceCodeRoot.get("template").get("id"));
sourceCodeSubquery.where(
criteriaBuilder.or(
criteriaBuilder.like(sourceCodeRoot.get("content"), likeKeyword),
criteriaBuilder.like(sourceCodeRoot.get("filename"), likeKeyword)));
predicates.add(criteriaBuilder.or(titlePredicate, descriptionPredicate, root.get("id").in(sourceCodeSubquery)));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import codezap.template.dto.request.CreateTemplateRequest;
import codezap.template.dto.request.UpdateTemplateRequest;
import codezap.template.repository.TemplateRepository;
import codezap.template.repository.TemplateSpecification;
import lombok.RequiredArgsConstructor;

@Service
Expand All @@ -39,30 +40,12 @@ public List<Template> getByMemberId(Long memberId) {
return templateRepository.findByMemberId(memberId);
}

public Page<Template> findByMemberAndKeyword(Long memberId, String keyword, Pageable pageable) {
keyword = "%" + keyword + "%";
return templateRepository.searchBy(memberId, keyword, pageable);
}

public Page<Template> findByMemberKeywordAndCategory(
Long memberId, String keyword, Long categoryId, Pageable pageable
) {
keyword = "%" + keyword + "%";
return templateRepository.searchBy(memberId, keyword, categoryId, pageable);
}

public Page<Template> findByMemberKeywordAndIds(
Long memberId, String keyword, List<Long> templateIds, Pageable pageable
) {
keyword = "%" + keyword + "%";
return templateRepository.searchBy(memberId, keyword, templateIds, pageable);
}

public Page<Template> findByMemberKeywordCategoryAndIds(
Long memberId, String keyword, Long categoryId, List<Long> templateIds, Pageable pageable
public Page<Template> findAll(
Long memberId, String keyword, Long categoryId, List<Long> tagIds, Pageable pageable
) {
keyword = "%" + keyword + "%";
return templateRepository.searchBy(memberId, keyword, categoryId, templateIds, pageable);
return templateRepository.findAll(
new TemplateSpecification(memberId, keyword, categoryId, tagIds), pageable
);
}

public Template updateTemplate(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
package codezap.template.service.facade;

import java.util.List;

import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import codezap.category.domain.Category;
import codezap.category.service.CategoryService;
import codezap.member.domain.Member;
import codezap.template.dto.request.CreateTemplateRequest;
import codezap.template.dto.request.UpdateTemplateRequest;
import codezap.template.dto.response.FindAllTemplatesResponse;
import lombok.RequiredArgsConstructor;

@Service
Expand All @@ -25,22 +21,6 @@ public Long createTemplate(Member member, CreateTemplateRequest createTemplateRe
return templateApplicationService.createTemplate(member, category, createTemplateRequest);
}

public FindAllTemplatesResponse findAllBy(
Long memberId,
String keyword,
Long categoryId,
List<Long> tagIds,
Pageable pageable
) {
if (categoryId == null) {
return templateApplicationService
.findByMemberKeywordAndCategoryOrTagIds(memberId, keyword, tagIds, pageable);
}
categoryService.validateExistsById(categoryId);
return templateApplicationService
.findByMemberKeywordOrTagIds(memberId, keyword, categoryId, tagIds, pageable);
}

public void update(Member member, Long templateId, UpdateTemplateRequest updateTemplateRequest) {
Category category = categoryService.fetchById(updateTemplateRequest.categoryId());
category.validateAuthorization(member);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,6 @@ public FindTemplateResponse getByIdAndMember(MemberDto memberDto, Long id) {
return templateApplicationService.getByMemberAndId(member, id);
}

public FindAllTemplatesResponse findAllBy(
MemberDto memberDto,
Long memberId,
String keyword,
Long categoryId,
List<Long> tagIds,
Pageable pageable
) {
memberService.validateMemberIdentity(memberDto, memberId);
return categoryTemplateApplicationService.findAllBy(memberId, keyword, categoryId, tagIds, pageable);
}

public void update(MemberDto memberDto, Long templateId, UpdateTemplateRequest updateTemplateRequest) {
Member member = memberService.getById(memberDto.id());
categoryTemplateApplicationService.update(member, templateId, updateTemplateRequest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,38 +59,10 @@ public FindAllTagsResponse getAllTagsByMemberId(Long memberId) {
return templateTagService.findAllByTemplates(template);
}

public FindAllTemplatesResponse findByMemberKeywordAndCategoryOrTagIds(
Long memberId,
String keyword,
List<Long> tagIds,
Pageable pageable
public FindAllTemplatesResponse findAllBy(
Long memberId, String keyword, Long categoryId, List<Long> tagIds, Pageable pageable
) {
if (tagIds == null) {
Page<Template> templates = templateService.findByMemberAndKeyword(memberId, keyword, pageable);
return makeTemplatesResponse(templates);
}

List<Long> templateIds = templateTagService.getTemplateIdContainTagIds(tagIds);
Page<Template> templates = templateService.findByMemberKeywordAndIds(memberId, keyword, templateIds, pageable);
return makeTemplatesResponse(templates);
}

public FindAllTemplatesResponse findByMemberKeywordOrTagIds(
Long memberId,
String keyword,
Long categoryId,
List<Long> tagIds,
Pageable pageable
) {
if (tagIds == null) {
Page<Template> templates = templateService.findByMemberKeywordAndCategory(memberId, keyword, categoryId,
pageable);
return makeTemplatesResponse(templates);
}

List<Long> templateIds = templateTagService.getTemplateIdContainTagIds(tagIds);
Page<Template> templates = templateService.findByMemberKeywordCategoryAndIds(memberId, keyword, categoryId,
templateIds, pageable);
Page<Template> templates = templateService.findAll(memberId, keyword, categoryId, tagIds, pageable);
return makeTemplatesResponse(templates);
}

Expand Down
Loading