[TIL] JPQL 정리

wannabeing·2025년 4월 17일
1

SPARTA-TIL

목록 보기
12/22

강의 내용 정리!

JPQL은

  • JPA가 SQL을 추상화하여 만든 객체지향 쿼리 언어이다.
  • 엔티티 객체를 대상으로 SQL Query를 작성할 수 있게 도와준다.
  • SQL을 추상화했기 때문에 특정 DB SQL에 의존하지 않는 장점이 있다.
  • JPQL은 SQL과 유사하며, 결국 SQL로 변환된다.

특징

  • JPA 사용하면서 객체중심적인 설계가 가능해졌다.
  • 특정 객체를 조회하는데는 편했지만,
    특정 조건을 가진 데이터를 가져오기엔 어려웠다.
  • 객체를 대상으로 검색한다. 테이블 대상이 아니다.
  • SQL을 추상화했기 때문에 다양한 DB에서 사용가능하다.
  • 컴파일 단계에서 엔티티와 필드의 타입을 확인한다.

동적쿼리

  • JQPL은 정적쿼리에 최적화 되어있다.
    따라서 문자열을 동적으로 다루어야한다.

반환타입

1) TypeQuery
주로 엔티티나 특정 객체를 반환할 때, 사용한다.
컴파일 시, 타입 검사를 할 수 있다는 장점이 있다.

// 특정 객체 반환
TypedQuery<Tutor> typeQuery1 = em.createQuery("select t from Tutor t", Tutor.class);

// String 반환
TypedQuery<String> typeQuery2 = em.createQuery("select t.name from Tutor t", String.class);

2) Query
반환 타입이 정확하지 않을 때 사용한다.
결과 처리를 할 때, 형변환이 필요할 수 있다.

Query query = em.createQuery("select t.name, t.age from Tutor t");

결과조회

1) getResultList()
결과가 하나 이상일 때, 사용한다.
결과가 없다면 빈 List를 반환한다.

List resultList = em.createQuery("select t from Tutor t").getResultList();

2) getSingleResult()
결과가 딱 하나일 때, 사용한다.
결과가 없거나 여러개이면 예외가 발생한다: NoResultException, NonUniqueResultException

Tutor singleResult = em.createQuery("select t from Tutor t where t.id = 1L", Tutor.class).getSingleResult();

@Embedded , @Embeddable

엔티티 안에 나만의 작은 엔티티를 만드는 느낌이다.

@Entity
public class Tutor {
		
		@Id
		@GeneratedValue
		private Long id;
		
		private String name;
		// Embedded 사용
		@Embedded
		private Period workPeriod;

}

// Embedded 정의
@Embeddable
public class Period {
  
  @Temporal(TemporalType.DATE)
  Date startDate;
  
  @Temporal(TemporalType.Date)
  Date endDate;
  
  public boolean isWork (Date date) {
	    // startDate <= date <= endDate 확인
      return (startDate == null || !date.before(startDate)) &&
             (endDate == null || !date.after(endDate));
  }
}
  • Tutor 엔티티는 Period라는 임베디드 타입을 갖고 있다.
  • 임베디드 타입인 Period는 두 개의 필드를 갖고 있고, isWork이라는 메서드를 하나 갖고 있다.
  • 임베디드 타입을 재사용할 수 있다.
  • 단일책임원칙(SRP)을 준수하는 방법이다.

프로젝션

  • 특정 필드만 선택하여 조회하는 방식이다.
  • 필요한 데이터만 조회하여 성능을 최적화하고 네트워크 비용을 줄일 수 있다.

Embeded 프로젝션

List<Period> resultList = em.createQuery("select t.period from Tutor t", Period.class).getResultList();
  • select period from Period p는 불가능하다.
  • @MappedSuperclass 어노테이션을 사용해서 상속받는 것이 더 편리하다!

페이징

  • setFirstResult(int startPosition): 조회 시작 위치
  • setMaxResult(int maxResult): 조회할 데이터 수
List<Tutor> tutorList = em.createQuery("select t from Tutor t order by t.age desc", Tutor.class)
                        .setFirstResult(5)
                        .setMaxResults(10)
                        .getResultList();

Q) 베이스엔티티 createdAt, updatedAt은 임베디드 타입으로?
@MappedSuperclass어노테이션을 사용한 상속이 더 편리하다.

profile
wannabe---ing

2개의 댓글

comment-user-thumbnail
2025년 4월 17일

JPQL...도 강의듣고 다시오겠습니다

1개의 답글