JPA 56

[JPA] 쿼리결과 변환하기 ( JPQL 함수 )

SELECT [ 컬럼 ] FROM [ 테이블 ] WHERE [ 조건 ] SELECT문은 FROM의 레코드집합에서 WHERE로 필터링 된 레코드 중 원하는 컬럼을 출력하는 쿼리문이다. 출력되는 컬럼은 조건에 따라 다른 값으로 변환될 수 있다. CASE 조건식 CASE 조건식은 JPQL에서도 사용가능하다. SELECT CASE WHEN m.age = 60 THEN '경로요금' ELSE '일반요금' END FROM Member m WHERE m.city IN ( SELECT c FROM City c WHERE c.name = '대구' ) 대구에 거주하는 회원의 나이를 출력하는 SELECT문인데, CASE 조건식으로 출력결과가 변환되었다. 나이가 10살 이하면 학생요금 나이가 60살 이상이면 경로요금 그 사이면..

JPA/JPQL 2023.06.14

[JPA] 서브쿼리 ( SubQuery )

SELECT [ 컬럼 ] FROM [ 테이블 ] WHERE [ 조건문 ] SELECT문은 FROM 레코드집합에서 WHERE 조건으로 필터링 된 레코드 중 원하는 컬럼을 출력한다. 만약 다른 테이블의 데이터가 필요하면 JOIN 연산을 사용한다. JOIN연산으로 다른 테이블의 데이터에 접근 가능하다. 말그대로 '데이터'에 접근이 가능하다. 예를들어, 학생 테이블을 조회하는데 수학성적이 필요하면 수학테이블에 접근하여 학생의 수학점수(데이터)를 가져 올 수 있다. JPQL 코드 SELECT s, m FROM Student s JOIN s.math m ON s.student_id = m.student_id 그런데 만약 '데이터'가 아니라 '정보'가 필요하다면 어떻게 할까? 데이터가 아니라 가공된 정보가 필요할 수..

JPA/JPQL 2023.06.14

[JPA] JOIN 과 JOIN FETCH의 차이

JOIN과 JOIN FETCH를 헷갈릴 수 있다. FROM 엔티티A JOIN FETCH 엔티티B FROM 엔티티A JOIN 엔티티B JOIN FETCH를 사용하면 엔티티A,엔티티B 둘 다 영속화 된다. JOIN을 사용하면 엔티티A만 영속화 된다. JOIN은 엔티티B를 굳이 영속화 할 이유는 없는데 엔티티B의 테이블에 있는 데이터가 필요한 경우 사용된다. 예를들어, 학생(Student)을 수학성적(Math)순으로 정렬한 데이터를 가져오고 싶다. 필요한 엔티티는 학생(Student) 엔티티이다. 수학(Math) 엔티티는 필요 없으나 ORDER BY로 정렬하려면 Math 테이블의 score 필드가 필요하다. 이런 경우에 일반 JOIN을 사용한다. SELECT s FROM Student s JOIN s.math..

JPA/JPQL 2023.06.14

[JPA] 페이징 API

MySQL, ORACLE의 페이징 처리는 복잡하기로 유명하다. JPA는 API 2개만 알면 페이징 구현이 가능하다. 그리고 JPA가 알아서 DB에 맞추어 복잡한 페이징 SQL을 자동 생성한다. 페이징 쿼리 1) String jpql = "select m from Member m order by m.name desc"; List resultList = entityManager.createQuery(jpql, Member.class) .setFirstResult(10) .setMaxResults(20) .getResultList(); 페이징 쿼리 2) String jpql = "SELECT e FROM Employee e ORDER BY e.id"; TypedQuery query = entityManager..

JPA/JPQL 2023.06.13

[JPA] JPQL이란?

JPA는 객체지향Application과 관계형DB 사이의 패러다임 불일치 문제를 해결한다. [JPA] 패러다임 불일치 어플리케이션 개발은 주로 객체지향언어로 이루어진다. 객체지향언어는 현실의 많은 문제를 코드로 구현하지만 문제가 있다. 데이터는 주로 관계형DB에 저장되는데 관계형DB와 어플리케이션은 lordofkangs.tistory.com JPA는 APP과 DB사이에서 자동으로 SQL문을 만들어 준다. 개발자는 객체지향 관점만 유지하면 된다. 그러나 JPA도 한계가 있다. 모든 쿼리를 객체지향방식으로 표현할 수 없다. 특히나 SELECT문은 조회에 여러 조건이 붙는 경우도 많고 조건이 동적으로 변하기도 한다. 그러므로 이를 커버할 무언가가 필요하다. 그것이 JPQL( Java Persistence Qu..

JPA/JPQL 2023.06.13

[JPA] 값타입 컬렉션 ( @ElementCollection, @CollectionTable )

[JPA] 임베디드 타입 ( @Embedded, @Embeddable ) @Id 어노테이션이 붙은 필드는 식별자를 의미한다. JPA는 식별자로 엔티티를 구분한다. @ManyToOne 등은 연관관계를 의미한다. JPA는 어노테이션으로 다른 엔티티와 연관관계를 정의한다. 이렇듯 개 lordofkangs.tistory.com 지난 포스팅에서 값타입의 개념과 임베디드타입을 다루어보았다. 테이블 컬럼에 삽입 될 데이터는 정합성을 가져야 한다. 컬럼과 매핑되는 엔티티는 정합성을 지킨 데이터를 가져야 한다. 원시타입은 JAVA에서 값복사를 지원하기에 정합성을 가지지만 참조타입은 참조복사를 하기에 다른 객체에서 데이터를 조작할 가능성이 있다. 그러므로 객체(컬렉션)는 참조복사가 아닌 값복사가 지원되어야 한다. 값타입이..

JPA/JPA Basic 2023.06.12

[JPA] 임베디드 타입 ( @Embedded, @Embeddable )

@Id 어노테이션이 붙은 필드는 식별자를 의미한다. JPA는 식별자로 엔티티를 구분한다. @ManyToOne 등은 연관관계를 의미한다. JPA는 어노테이션으로 다른 엔티티와 연관관계를 정의한다. 이렇듯 개발자는 JPA가 엔티티를 목적에 맞게 사용하도록 여러 어노테이션으로 '표시'를 남긴다. ( 엔티티 매핑, 연관관계 매핑, 상속관계 매핑, 영속성 전이 등등 ) 이와같은 엔티티 관련 필드는 제외하고, 단순히 컬럼에 값을 저장하기 위한 필드를 '값타입'이라 부른다. Student 엔티티 @Entity @Data public class Student { @Id @GeneratedValue @Column(name = "STUDENT_ID") private Long id; private String name; /..

JPA/JPA Basic 2023.06.09

[JPA] 영속성 전이와 고아객체

영속성 전이란, 부모가 자식의 영속성을 관리하는 기술이다. 영속성 전이는 주로 '합성관계'에서 사용되어야 한다. 합성관계는 부모가 자식을 제어하는 관계이다. 예를들어, MacBook은 일체형 노트북이다. MacBook노트북과 M1칩은 생명주기가 같다. 반면 조립형 컴퓨터는 다르다. 생산시기도 다른 부품들로 컴퓨터가 구성된다. 부모가 존재하기에 자식도 존재하는 관계가 합성관계이다. 이런 경우, 자식의 제어권은 부모에게 있기에 영속성도 부모의 제어권에 있도록 하는게 관리에 편하다. MacBook 엔티티 @Entity @Data public class MacBook { @Id @GeneratedValue private Long id; private String name; @OneToOne(cascade = C..

JPA/JPA Basic 2023.06.08

[JPA] 지연로딩(Lazy Loading)을 사용해야 하는 이유

[JPA] 프록시( Proxy ) 위 사진은 영속성 컨텍스트가 동작하는 과정이다. 엔티티 객체를 생성하려면 SELECT문을 DB에 실행해야 한다. APP과 DB는 서로 다른 영역으로 I/O가 발생한다. 잦은 I/O는 성능저하의 원인이 되므로 lordofkangs.tistory.com 프록시를 다루면서 지연로딩(Lazy Loading)에 대해서 다루어 보았다. A엔티티와 B엔티티는 서로 연관되어 있다. JPA가 A엔티티를 로드하면 A가 참조하는 B엔티티도 로드되어야 한다. 하지만 DB와 잦은 소통은 성능을 저하시킨다. JPA(하이버네이트)는 성능 최적화를 위해, 연관된 엔티티는 가짜 객체(프록시,Proxy)로 만들어 실제 엔티티 객체 생성을 지연시키는 전략을 구사한다. 이를 지연 로딩(Lazy Loadin..

JPA/JPA Basic 2023.06.08

[JPA] 프록시( Proxy )

위 사진은 영속성 컨텍스트가 동작하는 과정이다. 엔티티 객체를 생성하려면 SELECT문을 DB에 실행해야 한다. APP과 DB는 서로 다른 영역으로 I/O가 발생한다. 잦은 I/O는 성능저하의 원인이 되므로 성능 최적화를 위해 필요한 엔티티 객체만 생성해야 한다. Member 엔티티를 조회했다고 가정해보자. Member 엔티티는 Team엔티티와 연관관계에 있다. Member 엔티티 객체가 생성될 때 연관된 Team 엔티티도 만들어져야 한다. 그러나 연관된 모든 엔티티를 객체로 만들면 많은 I/O가 발생한다. 그래서 JPA(하이버네이트)는 성능 최적화를 위해, 연관된 객체는 가짜 객체(프록시,Proxy)로 만들고 실제 엔티티 객체 생성은 지연시키는 전략을 구사한다. 이를 지연 로딩(Lazy Loading)..

JPA/JPA Basic 2023.06.08