티스토리 뷰
프로젝션
1. SELECT m FROM MEMBER m -> 엔티티 프로젝션
JpqlMain
public class JpqlMain {
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(); // 비움
// 엔티티 프로젝션
List<Member> result = em.createQuery("select m from Member m", Member.class)
.getResultList();
// 여기서 m이 엔티티인데, 그럼 엔티티들이 반환된다.
// 얘는 영속성 컨텍스트에서 관리되는가?
// 정답은 바뀌면 관리가 되고, 안 바뀌면 관리가 안 된다.
Member findMember = result.get(0);
findMember.setAge(20); // 여기서는 바귐
tx.commit();
} catch (Exception e) {
tx.rollback();
e.printStackTrace();
} finally {
em.close();
}
emf.close();
}
}
실행 결
업데이트 쿼리 나갔다.
h2도
age가 변경되어 있다.
select 절이 엄청 여러개 나와도 영속성 컨텍스트에 다 걸려서 관리되게 되어 있다.
거기 있는 걸 바꾸면 정상적으로 데이터 반영도 잘 된다.
2. SELECT m.TEAM FROM MEMBER m -> 엔티티 프로젝션(결과가 멤버와 연관된 팀)
public class JpqlMain {
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(); // 비움
// 2. 엔티티 프로젝션 - 팀
List<Team> result = em.createQuery("select m.team from Member m", Team.class)
.getResultList();
tx.commit();
} catch (Exception e) {
tx.rollback();
e.printStackTrace();
} finally {
em.close();
}
emf.close();
}
}
이거 실행해보면
join이 된다. JPQL은 평범하게 생겼어도 SQL에서는 왜냐하면 Team을 찾아야 하므로,
그런데 SQL과 웬만하면 똑같이 써주는 게 바람직하므로, 식은 이렇게 써주는 게 더 낫다.
이렇게 해야 한 눈에 인식이 되니까.
뒤에 경로표현식에서 명시적 조인 / 묵시적 조인에서 자세히 배움.
3. SELECT m.address FROM Member m -> 임베디드 타입 프로젝션
public class JpqlMain {
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(); // 비움
// 3. 임베디드 타입 프로젝션
List<Address> result = em.createQuery("select o.address from Order o", Address.class)
.getResultList();
tx.commit();
} catch (Exception e) {
tx.rollback();
e.printStackTrace();
} finally {
em.close();
}
emf.close();
}
}
실행한 것 보면
Address 관련된 것만 잘 찾아옴을 확인할 수 있음.
주의, 값 타입이 어디 소속인지를 확실하게 명기해줘야 함.
4. SELECT m.username, m.age FROM Member m -> 스칼라 타입 프로젝션
public class JpqlMain {
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(); // 비움
// 4. 스칼라 타입 프로젝션
em.createQuery("select m.username, m.age from Member m")
.getResultList();
tx.commit();
} catch (Exception e) {
tx.rollback();
e.printStackTrace();
} finally {
em.close();
}
emf.close();
}
}
실행 결과
이렇게 원하는 값만 조회 가능
참고. DISTINCT 로 중복 제거
그런데, 타입이 다른데 어떻게 가져와야 하느냐에 대한 고민
그러한 방법
프로젝션 - 여러 값 조회 방법
1. Query 타입으로 조회
public class JpqlMain {
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(); // 비움
// 1) Query 타입으로 조회
List resultList = em.createQuery("select m.username, m.age from Member m")
.getResultList();
Object o = resultList.get(0);
Object[] result = (Object[]) o;
System.out.println("username : " + result[0]);
System.out.println("age : " + result[1]);
tx.commit();
} catch (Exception e) {
tx.rollback();
e.printStackTrace();
} finally {
em.close();
}
emf.close();
}
}
실행해보면 결과는
2. Object[ ] 타입으로 조회
// 2) Object[] 타입으로 조회
List<Object[]> resultList = em.createQuery("select 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 명령어로 조회(가장 깔끔)
일단 MemberDto 만들어놓고
public class MemberDto {
private String username;
private int age;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
밑줄 친 부분은 나중에 QueryDSL 을 쓰면 다 극복이 되는 부분이다.
자바 코르로 짤 때는 이 패키지명을 모두 임포트 해서 쓸 수가 있다.
지금은 문자이기 때문에, 다 적어줘야 한다.
728x90
반응형
'[데이터베이스] > JPQL' 카테고리의 다른 글
서브 쿼리 (0) | 2023.08.31 |
---|---|
조인 (2) - ON 절 (0) | 2023.08.30 |
조인 (1) - 내부 조인, 외부 조인, 세타 조인 (0) | 2023.08.30 |
페이징 API (0) | 2023.08.30 |
JPQL 소개 (0) | 2023.08.28 |
Comments