Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

Query By Example 본문

인프런/[인프런] Spring Data JPA

Query By Example

Seung__ 2021. 8. 31. 22:49

1. Query By Example


  • 엔티티 자체를 검색 조건으로 사용 가능
  • 엔티티로부터 Example 객체를 만들어 사용.
  • 스프링에서 기본적으로 Example 파라미터를 받을 수 있도록 지원함.
    @Test
    public void queryByExample(){
        Team teamA = new Team("teamA");
        em.persist(teamA);

        Member m1 = new Member("m1", 0, teamA);
        Member m2 = new Member("m2", 0, teamA);
        em.persist(m1);
        em.persist(m2);

        em.flush();
        em.clear();

        //when
        //Probe
        Member member = new Member("m1"); //엔티티 자체가 검색조건
        Example<Member> example = Example.of(member);

        //스프링에서 Example 을 파라미터로 받을 수 있도록 기본적으로 세팅해둠.
        List<Member> result = memberRepository.findAll(example);

        Assertions.assertThat(result.get(0).getUserName()).isEqualTo("m1");
    }

 

  • primitive type을 무시할 수 있도록 처리가 필요
    • int age -> null  불가능, primitive  type
    • ExampleMatcher 사용
  @Test
    public void queryByExample(){
        Team teamA = new Team("teamA");
        em.persist(teamA);

        Member m1 = new Member("m1", 0, teamA);
        Member m2 = new Member("m2", 0, teamA);
        em.persist(m1);
        em.persist(m2);

        em.flush();
        em.clear();

        //when
        //Probe
        Member member = new Member("m1"); //엔티티 자체가 검색조건
        ExampleMatcher exampleMatcher = ExampleMatcher.matching().withIgnorePaths("age");
        Example<Member> example = Example.of(member, exampleMatcher);

        //스프링에서 Example 을 파라미터로 받을 수 있도록 기본적으로 세팅해둠.
        List<Member> result = memberRepository.findAll(example);

        Assertions.assertThat(result.get(0).getUserName()).isEqualTo("m1");
    }
  • 연관관계인 경우 join이 해결되나...?
 @Test
    public void queryByExample(){
        Team teamA = new Team("teamA");
        em.persist(teamA);

        Member m1 = new Member("m1", 0, teamA);
        Member m2 = new Member("m2", 0, teamA);
        em.persist(m1);
        em.persist(m2);

        em.flush();
        em.clear();

        //when
        //Probe
        Member member = new Member("m1"); //엔티티 자체가 검색조건
        Team team  = new Team("teamA");
        member.setTeam(team); //연관관계를 만들어버려

        ExampleMatcher exampleMatcher = ExampleMatcher.matching().withIgnorePaths("age");
        Example<Member> example = Example.of(member, exampleMatcher);

        //스프링에서 Example 을 파라미터로 받을 수 있도록 기본적으로 세팅해둠.
        List<Member> result = memberRepository.findAll(example);

        Assertions.assertThat(result.get(0).getUserName()).isEqualTo("m1");
    }
  • 연관관계를 맺어주며  inner join으로 join이 해결됨.
    select
        member0_.member_id as member_i1_1_,
        member0_.created_date as created_2_1_,
        member0_.last_modified_date as last_mod3_1_,
        member0_.created_by as created_4_1_,
        member0_.last_modified_by as last_mod5_1_,
        member0_.age as age6_1_,
        member0_.team_id as team_id8_1_,
        member0_.user_name as user_nam7_1_ 
    from
        member member0_ 
    inner join
        team team1_ 
            on member0_.team_id=team1_.team_id 
    where
        member0_.user_name=? 
        and team1_.name=?
  • 정리
    • Probe: 필드에 데이터가 있는 실제 도메인 객체
    • ExampleMatcher: 특정 필드를 일치시키는 상세한 정보 제공, 재사용 가능
    • Example: Probe와 ExampleMatcher로 구성, 쿼리를 생성하는데 사용
  • 장점
    • 동적 쿼리를 편리하게 처리
    • 도메인 객체를 그대로 사용
    • 데이터 저장소를 RDB에서 NOSQL로 변경해도 코드 변경이 없게 추상화 되어 있음
      -->QueryByExampleExecutor의 패키지가 spring-data-commons임 ㅋㅋ
    • 스프링 데이터 JPA JpaRepository 인터페이스에 이미 포함
  • 단점
    • 조인은 가능하지만 내부 조인(INNER JOIN)만 가능함 외부 조인(LEFT JOIN) 안됨..ㅜㅜㅜㅜ
    • 다음과 같은 중첩 제약조건 안됨
    • firstname = ?0 or (firstname = ?1 and lastname = ?2)
    • 매칭 조건이 매우 단순함
    • 문자는 starts/contains/ends/regex
    • 다른 속성은 정확한 매칭( = )만 지원
  • 정리
    • 실무에서 사용하기에는 매칭 조건이 너무 단순하고, LEFT 조인이 안됨
      실무에서는 QueryDSL을 사용하자

 

 

2. GitHub : 210831 QueryByExample


 

GitHub - bsh6463/SpringDataJpa

Contribute to bsh6463/SpringDataJpa development by creating an account on GitHub.

github.com

 

'인프런 > [인프런] Spring Data JPA' 카테고리의 다른 글

Native Query  (0) 2021.09.01
Projections  (0) 2021.08.31
SpringDataJpa의 구현체  (0) 2021.08.31
Web 확장 : 도메인 클래스 컨버터, 페이징 & 정렬  (0) 2021.08.31
Auditing  (0) 2021.08.30
Comments