프로젝션(SELECT)
프로젝션
SELECT 절에 조회할 대상을 지정하는 것
프로젝션 대상: 엔티티, 임베디드 타입, 스칼라 타입(숫자, 문자등 기본 데이터 타입)
SELECT m FROM Member m -> 엔티티 프로젝션
SELECT m.team FROM Member m -> 엔티티 프로젝션
SELECT m.address FROM Member m -> 임베디드 타입 프로젝션
SELECT m.username, m.age FROM Member m -> 스칼라 타입 프로젝션
DISTINCT로 중복 제거
엔티티 타입으로 조회하는 경우 엔티티를 반환한다. 이 반환된 엔티티는 영속성 컨텍스트 관리 대상일까? 엔티티 컬렉션을 반환한다면 그 엔티티 하나하나 다 영속성 컨텍스트 관리된다.
조인
묵시적 조인
명시적 조인(권장)
묵시적 조인
List<Team> teamResult = em.createQuery("select m.team from Member m", Team.class).getResultList();
join연산은 성능에 영향을 주는 튜닝할 요소들이 많기 때문에 JPQL에서 m.team을 조회할 때에 join연산이 일어나는데 최대한 SQL과 유사하게 작성해야한다.
Member와 Team을 조인해서 조인한 Team의 엘리엇을 t로 가져온다.(SQL이 예측되도록)
List<Team> teamResult = em.createQuery("select t from Member m join m.team t", Team.class).getResultList();
Address 값 타입만 조회👇🏻
em.createQuery("select o.address from Order o", Address.class).getResultList();
스칼라 타입 값 2개 조회
em.createQuery("select distinct m.username, m.age from Member m").getResultList();
프로젝션 - 여러 값 조회 SELECT m.username, m.age FROM Member m
Query로 조회 : 값이 여러개이므로 값을 특정하지 못하기 때문 타입을 알지 못할 때(타입을 명시해주지 않으면) 리턴타입은 Query가 된다. 이렇게 반환된 query에는 object가 들어가있다.
Query query = em.createQuery("select m.username,m.age from Member m");
2. Object[ ]로 형변환(캐스팅)해서 조회. .getResultList()를 리스트 타입으로 반환한다. resultList의 첫번째 객체를 Object[ ]로 형변환한다! Object의 0번째, 1번째 값들이 각각 username과 age에 해당한다!
List resultList = em.createQuery("select distinct m.username, m.age from Member m").getResultList();//현재 타입이 없음.
Object o = resultList.get(0);//Object배열이 들어가있을 것이다!
Object[] result = (Object[]) o;
System.out.println("username = " + result[0]);
System.out.println("age = " + result[1]);
위의 코드에서 리턴되는 List의 제네릭을 Object[ ]로 하면 자동 캐스팅된다.
List<Object[]> resultList = em.createQuery("select distinct m.username, m.age from Member m").getResultList();//현재 타입이 없음.
Object[] result = resultList.get(0);
System.out.println("username = " + result[0]);
System.out.println("age = " + result[1]);
3. new 명령어로 조회 => 마치 별칭 자리에 생성자를 호출하듯이!
단순 값을 DTO로 바로 조회 SELECT new jpabook.jpql.UserDTO(m.username, m.age) FROM
Member m
패키지명을포함한전체클래스명입력 (한계점) =>QueryDSL을 이용해서 Java코드로 짜면 import해서 사용할 수 있다.
순서와 타입이 일치하는 생성자 필요
List<MemberDTO> result = em.createQuery("select distinct new jpql.MemberDTO(m.username, m.age) from Member m", MemberDTO.class)
.getResultList();//현재 타입이 없음.
MemberDTO memberDTO = result.get(0);
System.out.println("memberDTO.username = " + memberDTO.getUsername());
System.out.println("memberDTO.age = " + memberDTO.getAge());
용어 정리 SELECT (*) FROM Member m (*) :엘리아스(별칭)
Last updated
Was this helpful?