작성자 : 김여원, 박재용
기존 코드
for (String key : keywords) {
postList.addAll(postRepository.findAllByTitleContainsOrContentContaining(key, key));
List<Keyword> findKeyWords = keywordRepository.findAllByKeywordContains(key);
for (Keyword k : findKeyWords) {
postList.add(k.getPost());
}
}
Set<Post> allPosts = new HashSet<>(postList);
List<Post> companyPost = allPosts.stream().filter(p -> Objects.equals(p.getCategory().getCompany().getId(), company.getId())).collect(Collectors.toList());
Collections.sort(companyPost, Comparator.comparingInt(Post::getScore).reversed
개선된 코드
for (String key : keywords) {
postList.addAll(postRepositoryImpl.findAllByContainingKeyword(key));
}
List<Post> companyPost = postList.stream().distinct().filter(p -> Objects.equals(p.getCategory().getCompany().getId(), company.getId()))
.sorted(Comparator.comparingInt(Post::getScore).reversed()).collect(Collectors.toList());
1️⃣ Before PostRepository와 KeywordRepository에서 제목과 내용, 키워드 조회를 각각 조회.
After 동적 쿼리와 fetch join을 통해 한 번에 키워드 조회
2️⃣ Before 이중 for문으로 조회한 키워드들의 post를 다시 postList에 추가
After 동적 쿼리로 return 받은 타입이 List<Post>로 바뀌었으므로, for문 한 번으로 추가 가능.
Keyword 들어간 Post 찾기
@Repository
@Transactional
public class PostRepositoryImpl {
@PersistenceContext
private EntityManager entityManager;
private final QPost post = QPost.post;
private final QMember member = QMember.member;
private final QKeyword keyword = QKeyword.keyword1;
public List<Post> findAllByContainingKeyword(String k) {
JPAQuery<Post> result = new JPAQuery<>(entityManager);
return new ArrayList<>(result.select(post)
.from(post)
.innerJoin(post.member, member).fetchJoin()
.innerJoin(post.keywords, keyword).fetchJoin()
.where(post.title.contains(k)
.or(post.content.contains(k))
.or(keyword.keyword.contains(k)))
.distinct()
.fetch());
}
Post에서 Keyword 찾기
@Repository
@Transactional
public class KeywordRepositoryImpl {
@PersistenceContext
private EntityManager entityManager;
private final QKeyword keyword = QKeyword.keyword1;
private final QPost newPost = QPost.post;
public List<Keyword> findAllByPost(Post post) {
JPAQuery<Keyword> result = new JPAQuery<>(entityManager);
return new ArrayList<>(result.select(keyword)
.from(keyword)
.innerJoin(keyword.post, newPost).fetchJoin()
.where(newPost.id.eq(post.getId()))
.distinct()
.fetch());
}