Member member = new Member();
member.setUsername("member1")
member.setAge(10);
em.persist(member);
List<Member> result = em.createQUery("select m from Member m", Member.class)
.getResultList();
일반적인 조회 방법은 여태 싸웠던 방식 그대로 사용하면 된다. 근데 여기서 한 가지 의문점이 든다. 저렇게 다건을 조회해와도 영속성 컨텍스트에 올라갈까?
em.flush();
em.clear();
List<Member> result = em.createQUery("selecdt m from Member m", Member.class)
.getResultList();
Member findMember = result.get(0);
처음 예제에서 추가로 코드를 넣어줬다. 먼저 영속성 컨텍스트를 모두 비우고 Member 를 조회한다. 그리고 나서 Member를 하나 가져오고 그 Member 의 Age 를 바꿔준다. 만약 UPDATE 쿼리가 나간다면 영속성 컨텍스트에서 관리자 되고 있는 것이고, 나가지 않는다면 영속성 컨텍스트에 없다는 말이다.
실행 후 출력 로그를 확인해보면 UPDATE 쿼리가 잘 나가는 것을 볼 수 있다. JPA 에서 1개든 10개든 100개든 조회해오는 모든 데이터는 영속성 컨텍스트로 올라간다.
List<Team> result = em.createQuery("select m.team from Member m", Team.class)
.getResultList();
코드를 위와 같이 수정한다. 조회를 해 오는 데이터가 m.team 이므로 Team.class 로 변경해줘야 한다. 그리고 실행을 해보면 JOIN 쿼리가 나간다.
뭔가 나는 JPQL 을 심플하게 작성했는데 쿼리가 복잡하게 나간다.좋은 기능 같지만 JPQL 도 최대한 쿼리와 비슷하게 작성해야 함이 맞다. JOIN 의 경우엔 성능과 직접적으로 연관되어 있는 기능이기도 하고 튜닝도 할 수 있기 때문에 한 눈에 보여야 한다. 그래서 코드를 아래와 같이 수정해주면 된다.
List<Team> reulst = em.createQuery("select m.team from Member m join m.team t",
Team.class)
.getReulstList();
List<Address> result = em.createQuery("select o.address from Order o", Address.class)
. getReulstList();
임베디드 타입 프로젝션은 특이한 점은 한계점이 존재한다.
List<Address) result = em.createQuery("select a from Address a", Address.class)
.getResultList();
em.createQUery("select m.username, m.age from Member m")
.getReulstList();
이 스칼라 타입 프로젝션이 일반 SQL 의 스칼라 프로젝션 타입과 비슷하다. 내용이 많으므로 {여러 값 조회} 에서 풀겠따.
em.createQuery("select distinct m.username, m.age from Member m")
.getReulstList();
SELECT 다음에 DISTINCT 키워드를 넣어주면 된다.
em.createQuery("select distinct m.username, m.age from Member m")
.getResultList();
스칼라 타입에는 지금 username 과 age 두 개의 필드가 존재한다. 이 데이터를 어떻게 가져와야 할까?
List resultList = em.createQuery("select distinct m.username, m.age from Member m")
.getResultList();
Query 타입의 반환 값은 List이다. 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("result = " + result[0]);
System.out.println("result = " + result[1]);
List 제네릭에 Object[] 를 넣어주면 형변환 작업을 생략할 수 있다.
new 명령어로 조회
먼저 MemberDTO 클래스를 생성한다.
그리고 실행 클래스에서 코드를 수정해준다.
List resultList = em.createQuery("select new jpql.MEMBERDTO(m.username, m.age) from Member m", MemberDTO.class)
.getResultList();
MemberDTO memberDTO = reulst.get(0);
System.out.println("memberDTO = " + memberDTO.getUsername());
System.out.println("memberDTO = " + memberDTO.getAge());
뭔가 원하는 대로 작동이 되지만 뭔가 쿼리에 구구절절 패키지명을 적어야 하는게 맞나 싶기도 하다. 근데 추후 QueryDSL 을 사용하면 이런 불편한 부분을 극복할 수 있게 된다.