[Spring Boot] JPQL / 프로젝션 / createQuery / select, join

seulki·2022년 12월 13일
0

[springboot]

목록 보기
23/27

🎈 프로젝션

  • JPQL에서는 출력하고자 하는 컬럼을 프로젝션이라고 한다.
  • select 절에 조회할 대상을 지정하는 것
  • select m from Member m
    -> Member 엔티티 조회
  • select m.team from Member m
    -> Member와 관련된 team을 가지고 온다. (양방향 매핑)
  • select m.username, m.age from Member m
    -> Member 엔티티에 있는 username, age를 조회

public class Main {

	public static void main(String[] args) {

		EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
		EntityManager em = emf.createEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		
		try {
			Member member = new Member();
			member.setUsername("member1");
			member.setAge(10);
			em.persist(member);
			
			em.flush();
			em.clear();
			
			// 영속성 컨텍스트에 관리가 될까 안될까? O
			// 영속성 컨텍스트가 비워졌을 때, 영속성 컨텍스트에 들어오기 위해서
            // 일부러 select문을 날리는 경우가 있다. 
			List<Member> result = em.createQuery("select m from Member m", Member.class).getResultList();
			
			// update가 된다 -> 영속성 컨텍스트에서 관리가 된다.
			// update 가 안된다 -> 영속성 컨텍스트에서 관리가 안된다.
			Member findMember = result.get(0);
			findMember.setAge(20);
	       
			tx.commit(); 
		} catch (Exception e) {
			tx.rollback();
		}finally {
			em.close();
			emf.close();
		}
	}
}
  • 영속성 컨텍스트가 비워지고 select를 하게 되면, 다시 영속성 컨텍스트 영역에
    데이터가 담기게 된다.
  • 영속성 컨텍스트에 데이터가 담겼기 떄문에, set으로 update시 값이 출력될 수 있는 것이다.
  • 영속성 컨텍스트가 비워진 상태에서, 일부러 영속성 컨텍스트에 데이터를 담기 위해서 select 하는 경우가 있다.


✨ createQuery - join

  • 이렇게 Member에서 Team을 가져올 수도 있지만,
    join을 할때는 명시적으로 join을 했음을 보여주는 것이 권장된다.
    List<Team> result = em.createQuery("select m.team from Member m", Team.class).getResultList();

  • 이렇게 명시적으로 join 을 써주는 것이 좋다.
    List<Team> result = em.createQuery("select t from Member m join m.team t", Team.class).getResultList();



👌 임베디드 타입 컬럼 조회하기

  • Order 클래스에 임베디드타입인 Address컬럼을 불러오고 싶을 때
    em.createQuery("select o.address from Order o",Address.class).getResultList();


  • Address 임베디드 클래스는, Orders 안에 있는 클래스일뿐, 엔티티가 아니기 때문에 테이블처럼 사용할 수 없다.
    em.createQuery("select o.address from Address o", Address.class).getResultList();
public static void main(String[] args) {

		EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
		EntityManager em = emf.createEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		
		try {
			Member member = new Member();
			member.setUsername("member1");
			member.setAge(10);
			em.persist(member);
			
			em.flush();
			em.clear();
			
			em.createQuery("select o.address from Order o", Address.class).getResultList();
			
			// Orders 안에 있는 클래스일뿐, 엔티티가 아니기 때문에 테이블처럼 사용할 수 없다.
			em.createQuery("select o.address from Address o", Address.class).getResultList();
	
			// 함수를 사용할 때는 sql과 거의 호환이 된다.
			em.createQuery("select distinct m.username, m.age from Member m").getResultList();

	       
			tx.commit(); 
		} catch (Exception e) {
			tx.rollback();
		}finally {
			em.close();
			emf.close();
		}
	}


🎈 값을 Object 타입으로 받기

  • 받아오는 값의 타입을 지정하지 못할 때 Object로 받아온다.
    String과 int를 동시에 받아온다.
  1. 1번 방법 - Object

  2. 2번 방법 - Object

  3. 3번 방법 -> 가장 많이 사용
    특정 값을 받아올 DTO를 생성하여 값을 받아온다.

  • username. age 값을 받아올 DTO를 생성

  • DTO의 패키지명을 new 뒤에 써준다.

 List<MemberDTO> result = em.createQuery("select new com.koreait.jpql.MemberDTO( m.username, m.age) from Member m").getResultList();

MemberDTO memberDTO = result.get(0);
System.out.println("username : " + memberDTO.getUsername());
System.out.println("age : " + memberDTO.getAge());
profile
웹 개발자 공부 중

0개의 댓글