Skip to content

Commit ebc70e7

Browse files
committed
[Feat]: 게시글 검색 기능 구현
1 parent cae613d commit ebc70e7

File tree

3 files changed

+85
-1
lines changed

3 files changed

+85
-1
lines changed

back/src/main/java/com/back/domain/post/repository/PostRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@
88
* 게시글 엔티티에 대한 데이터베이스 접근을 담당하는 JpaRepository.
99
*/
1010
@Repository
11-
public interface PostRepository extends JpaRepository<Post, Long> {
11+
public interface PostRepository extends JpaRepository<Post, Long>, PostRepositoryCustom {
1212
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.back.domain.post.repository;
2+
3+
import com.back.domain.post.dto.PostSearchCondition;
4+
import com.back.domain.post.entity.Post;
5+
import org.springframework.data.domain.Page;
6+
import org.springframework.data.domain.Pageable;
7+
8+
public interface PostRepositoryCustom {
9+
Page<Post> searchPosts(PostSearchCondition postSearchCondition, Pageable pageable);
10+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package com.back.domain.post.repository;
2+
3+
import com.back.domain.post.dto.PostSearchCondition;
4+
import com.back.domain.post.entity.Post;
5+
import com.back.domain.post.enums.PostCategory;
6+
import com.back.domain.post.enums.SearchType;
7+
import com.querydsl.core.types.dsl.BooleanExpression;
8+
import com.querydsl.jpa.impl.JPAQuery;
9+
import com.querydsl.jpa.impl.JPAQueryFactory;
10+
import lombok.RequiredArgsConstructor;
11+
import org.springframework.data.domain.Page;
12+
import org.springframework.data.domain.Pageable;
13+
import org.springframework.data.support.PageableExecutionUtils;
14+
import org.springframework.stereotype.Repository;
15+
import org.springframework.util.StringUtils;
16+
17+
import java.util.List;
18+
19+
import static com.back.domain.post.entity.QPost.post;
20+
import static com.back.domain.user.entity.QUser.user;
21+
22+
@RequiredArgsConstructor
23+
@Repository
24+
public class PostRepositoryCustomImpl implements PostRepositoryCustom {
25+
private final JPAQueryFactory queryFactory;
26+
27+
@Override
28+
public Page<Post> searchPosts(PostSearchCondition condition, Pageable pageable) {
29+
List<Post> posts = queryFactory
30+
.selectFrom(post)
31+
.leftJoin(post.user, user).fetchJoin()
32+
.where(getCategoryCondition(condition.category()),
33+
getSearchCondition(condition.keyword(), condition.searchType()))
34+
.orderBy(post.createdDate.desc())
35+
.offset(pageable.getOffset())
36+
.limit(pageable.getPageSize())
37+
.fetch();
38+
39+
JPAQuery<Long> count = queryFactory
40+
.select(post.count())
41+
.from(post)
42+
.where(
43+
getCategoryCondition(condition.category()),
44+
getSearchCondition(condition.keyword(), condition.searchType())
45+
);
46+
47+
return PageableExecutionUtils.getPage(posts, pageable, count::fetchOne);
48+
}
49+
50+
/**
51+
* 1차 필터링 (CHAT, SCENARIO, POLL)
52+
* category 조건이 null이 아니면 필터링 조건 추가
53+
*/
54+
private BooleanExpression getCategoryCondition(PostCategory category) {
55+
return category != null ? post.category.eq(category) : null;
56+
}
57+
58+
/**
59+
* 2차 필터링 (TITLE, TITLE_CONTENT, AUTHOR)
60+
* fixme 현재 like 기반 검색 - 성능 최적화를 위해 추후에 수정 예정
61+
*/
62+
private BooleanExpression getSearchCondition(String searchKeyword, SearchType searchType) {
63+
if (!StringUtils.hasText(searchKeyword) || searchType == null) {
64+
return null;
65+
}
66+
67+
return switch (searchType) {
68+
case TITLE -> post.title.containsIgnoreCase(searchKeyword);
69+
case TITLE_CONTENT -> post.title.containsIgnoreCase(searchKeyword)
70+
.or(post.content.containsIgnoreCase(searchKeyword));
71+
case AUTHOR -> post.user.nickname.containsIgnoreCase(searchKeyword);
72+
};
73+
}
74+
}

0 commit comments

Comments
 (0)