[SPRING] FOR 를 이용해 SQL문으로는 닿을 수 없는 ENTITY 내부 검색하기

THOVY·2022년 10월 26일
0

PROJECT

목록 보기
2/20

🤷‍♂️ SITUATION

  1. POST ENTITY 는 EMOTION ENTITY 를 여러개 갖고 있다. 그래서 List 이 Post 에 있다.

    // Post.java
    
    public class Post{
        ...
    
        @ManyToMany(fetch = FetchType.EAGER)
        @JoinColumn(name = "emotionId", referencedColumnName = "emotionId")
        private List<Emotion> emotion;
    
    }
  2. List 는 SQL 에서 인식하지 못한다.

🤔 What I Want

  1. word 를 입력하면 title, contents 그리고 emotion 에 있는 emotionwordword 가 포함된 post 를 검색하고 싶다!
  2. sql 문을 작성하자
    SELECT * FROM post WHERE TITLE LIKE %:search% OR CONTENTS LIKE %:search% OR EMOTION.EMOTIONWORD LIKE %:search%
// PostRepository.java
  
@Query(value = "SELECT * FROM post WHERE TITLE LIKE %:search% OR CONTENTS LIKE %:search% OR EMOTION.EMOTIONWORD LIKE %:search%", nativeQuery = true)
public List<Post> findBySearch(@Param("search") String search);
  1. 안되지!❌

❌ ERROR

HIBERNATE CAN'T FIND "EMOTION"

✅SOLUTION

KEYSET + contains 😲

그래서 고민 끝에

  1. SQL 은
    SELECT * FROM post WHERE TITLE LIKE %:search% OR CONTENTS LIKE %:search%
    이렇게 쓰고
  2. KEYSET 을 이용한 뒤 contains ❗
    // PostServiceImpl.java
    public List<Post> findByWord(String word){
      List<Post> postList = postRepository.findBySearch(word);
    ✨✨
      for(Post posttmp : postRepository.findAll()){
          for (Emotion emotiontmp : posttmp.getEmotion()){
              if(emotiontmp.getEmotionWord().contains(search)){
                  postList.add(posttmp);
              }
          }
      }
    ✨✨
      return postList;
    }

이렇게 sql 이 해결할 수 없다면 java 가 해결해준다.

어느 것 하난 소홀하지 말자!

WHY "KEYSET"

keyset 이 제일 빠르고 간편하다. 참고

추후에 post 가 많아졌을 때 findAll 한 posts 를 모두 for문 돌리려면 엄청 오래걸릴텐데 제일 빠른 거 써야지!

행복하다.

어쩌면 나는 아주 멍청이는 아닐지도...?

profile
BEAT A SHOTGUN

0개의 댓글