728x90
320x100
🎯 오늘의 목표
- 피드 검색 조회
⚙️ 진행한 작업
- 피드 검색 조회
🛠️ 개발내용
📌 QueryDSL 적용법
아래의 포스팅 참고!
[JPA/QueryDSL] 적용하기
은근히 적용하기 빡센 쿼리 데셀....정리해놓자 📌 build.gradle 추가dependencies { implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta'}def generated = "build/generated"so
ddururiiiiiii.tistory.com
📌 FeedRepositoryCustom.java 생성
package ddururi.bookbookclub.domain.feed.repository;
import ddururi.bookbookclub.domain.feed.entity.Feed;
import org.springframework.data.domain.Pageable;
import java.util.List;
/**
* 피드 QueryDSL 커스텀 레포지토리 인터페이스
*/
public interface FeedRepositoryCustom {
/** 키워드 검색 기반 피드 조회 */
List<Feed> searchFeeds(String keyword, Pageable pageable);
}
📌 FeedRepositoryImpl.java 생성
package ddururi.bookbookclub.domain.feed.repository;
import com.querydsl.jpa.impl.JPAQueryFactory;
import ddururi.bookbookclub.domain.feed.entity.Feed;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import org.springframework.data.domain.Pageable;
import java.util.List;
import static ddururi.bookbookclub.domain.feed.entity.QFeed.feed;
/**
* 피드 QueryDSL 커스텀 레포지토리 구현체
*/
@Repository
@RequiredArgsConstructor
public class FeedRepositoryImpl implements FeedRepositoryCustom {
private final JPAQueryFactory queryFactory;
@Override
public List<Feed> searchFeeds(String keyword, Pageable pageable) {
// 블라인드 제외 + content, title, author, publisher 검색 + 최신순 정렬
return queryFactory
.selectFrom(feed)
.leftJoin(feed.book).fetchJoin()
.where(
feed.isBlinded.isFalse()
.and(
feed.content.containsIgnoreCase(keyword)
.or(feed.book.title.containsIgnoreCase(keyword))
.or(feed.book.author.containsIgnoreCase(keyword))
.or(feed.book.publisher.containsIgnoreCase(keyword))
)
)
.orderBy(feed.createdAt.desc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
}
}
- 검색은 피드내용, 저자, 책제목, 출판사 통합하여 검색할 수 있도록 함
📌 FeedRepository.java 수정
package ddururi.bookbookclub.domain.feed.repository;
import ddururi.bookbookclub.domain.feed.entity.Feed;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
/**
* 피드 JPA 레포지토리
*/
public interface FeedRepository extends JpaRepository<Feed, Long>, FeedRepositoryCustom {
/** 블라인드 되지 않은 피드 페이징 조회 */
Page<Feed> findByIsBlindedFalse(Pageable pageable);
/** 블라인드 되지 않은 피드 다건 조회 (id 리스트 기반) */
List<Feed> findByIdInAndIsBlindedFalse(List<Long> ids);
}
- FeedRepositoryCustom을 extends 받음
📌 FeedService.java 수정
/**
* 피드 목록 조회 (검색기능, 페이징, 좋아요 수, 좋아요 여부 포함)
* @param pageable 페이징 요청 정보
* @param userId 현재 사용자 ID
* @return 피드 목록 (페이지 형태)
*/
public List<FeedResponse> searchFeeds(String keyword, Pageable pageable, Long userId) {
List<Feed> feeds = feedRepository.searchFeeds(keyword, pageable);
return feeds.stream()
.map(feed -> {
long likeCount = likeService.getLikeCount(feed.getId());
boolean liked = likeService.hasUserLiked(userId, feed.getId());
return new FeedResponse(feed, likeCount, liked);
})
.toList();
}
📌 FeedController.java 수정
/**
* 피드 목록 조회 (검색 기능, 페이징, 좋아요 수, 좋아요 여부 포함)
* @param pageable 페이징 요청 정보
* @param userDetails 현재 로그인한 사용자 정보
* @return 피드 목록 (페이지 포함)
*/
@GetMapping("/search")
public ResponseEntity<ApiResponse<List<FeedResponse>>> searchFeeds(
@RequestParam String keyword,
Pageable pageable,
@AuthenticationPrincipal CustomUserDetails userDetails
) {
List<FeedResponse> feeds = feedService.searchFeeds(keyword, pageable, userDetails.getUser().getId());
return ResponseEntity.ok(ApiResponse.success(feeds));
}
[포스트맨으로 테스트하기]
GET http://localhost:8080/api/feeds/search?keyword=미움받을&size=10&page=0
[테스트 결과 : 성공]
검색 결과가 없을땐 이렇게 뜬다
728x90
320x100
'💻 뚝딱뚝딱 > 북북클럽' 카테고리의 다른 글
[개발일지 #033] 책(Book) 중복 등록 시 예외 처리 하기 (0) | 2025.05.02 |
---|---|
[개발일지 #032] 각종 피드 조회 (특정 회원의 피드 목록 조회, 특정 회원이 좋아요 누른 피드 목록 조회) (0) | 2025.05.02 |
[JPA/QueryDSL] 적용하기 (0) | 2025.05.02 |
[개발일지 #030] 좋아요(Like) 랭킹에서 피드 상세정보 함께 내려주기 (0) | 2025.05.02 |
[개발일지 #029] 책(Book) - Spring WebClient로 외부 API 연동: KakaoBookClient 구현 (0) | 2025.05.01 |