이번 스프링에서 밀어주는 query 탐색법이다. Entity를 생성해서 Example 객체로 변환, repository로 찾아버림
JPA RepositoryfindAll과 같은 메서드에 이미 Example 버전을 만들어 놨다.
(left join이 안되어서 실무에선 주로 QueryDsl을 사용한다.)
버전 1. 그냥 Entity객체 생성해서 실행
@Test
public void queryByExampleTest() throws Exception {
//given
Team teamA = new Team("teamA");
Member m1 = new Member("m1",0,teamA);
Member m2 = new Member("m2",0,teamA);
em.persist(teamA);
em.persist(m1);
em.persist(m2);
em.flush();
em.clear();
//when
Member targetMem = new Member("m1");//찾고싶은 유저 Entity
Example<Member> example = Example.of(targetMem);
memberRepository.findAll(example);
//then
}
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_.username as username7_1_
from
member member0_
where
member0_.age=0
and member0_.username=?
버전2. Example Matcher로 조건 걸기
@Test
public void queryByExampleTest() throws Exception {
//given
Team teamA = new Team("teamA");
Member m1 = new Member("m1",0,teamA);
Member m2 = new Member("m2",0,teamA);
em.persist(teamA);
em.persist(m1);
em.persist(m2);
em.flush();
em.clear();
//when
Member targetMem = new Member("m1");//찾고싶은 유저 Entity
****
ExampleMatcher matcher = ExampleMatcher.matching()
.withIgnorePaths("age");//age는 무시하는 matcher 조건 생성 (username만 가져오게 한다)
****
Example<Member> example = Example.of(targetMem,matcher);
memberRepository.findAll(example);
//then
}
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_.username as username7_1_
from
member member0_
where
member0_.username=? //age가 무시되었다.
Matcher에 다양한 기능이 있다. 공식 spring 문서 참조.
버전3 innerjoin
@Test
public void queryByExampleTest() throws Exception {
//given
Team teamA = new Team("teamA");
Member m1 = new Member("m1",0,teamA);
Member m2 = new Member("m2",0,teamA);
em.persist(teamA);
em.persist(m1);
em.persist(m2);
em.flush();
em.clear();
//when
Member targetMem = new Member("m1");//찾고싶은 유저 Entity
***
Team team = new Team("teamA");
***
targetMem.setTeam(team);
ExampleMatcher matcher = ExampleMatcher.matching()
.withIgnorePaths("age");//age는 무시하는 matcher 조건 생성 (username만 가져오게 한다)
Example<Member> example = Example.of(targetMem,matcher);
memberRepository.findAll(example);
//then
}
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_.username as username7_1_
from
member member0_
inner join
team team1_
on member0_.team_id=team1_.team_id
where
team1_.name=?
and member0_.username=?
장점
- 동적 쿼리를 편리하게 처리
- 도메인 객체를 그대로 사용
- NoSQL로 사용해도 변환 된다.(SpringData쪽 인터페이스를 사용)
- 스프링 데이터 JPA 인터페이스에 이미 포함
JpaRepository
주의사항 💥한계
- inner join까지만 가능하다. left join 등 불가, 아직 부족한 점이 많다. 실무에선 QueryDSL을 사용
'스프링 > JPA' 카테고리의 다른 글
| [JPA 기초] JPA에서 기존 엔티티의 값을 수정하는 방법 (부제 : 왜 em.merge() 사용을 지양해야하는가) (0) | 2022.04.05 |
|---|---|
| [JPA 기초] 기본 Entity 설정시 사용되는 annotation 정리 (0) | 2022.04.05 |
| `SpringDataJPA` 기본 save 작동 과정 (merge와 persist를 중심으로 효율성 개선) (0) | 2022.02.27 |
| API 구현시 Parameter로 자동 Paging 객체 매핑하기 (0) | 2022.02.25 |
| Entity를 변경/생성할 때, 변경자와 시간 히스토리 관리하려면? (0) | 2022.02.24 |