[JPA] 객체 지향 쿼리, JPQL에 대해 알아보자🤗

sorzzzzy·2021년 11월 10일
0

TIL

목록 보기
9/36
post-thumbnail

JPA는 복잡한 검색 조건을 사용해서 엔티티 객체를 조회할 수 있는 다양한 쿼리 기술을 지원한다.
이번 글에서는 다양한 객체지향 쿼리 중 JPQL에 대해 다뤄볼 것이다!


✔️JPQL 이란

(Java Persistence Query Language)

  • 테이블이 아닌 엔티티 객체를 대상으로 검색하는 객체지향 쿼리
  • SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않음
  • JPA는 JPQL을 분석한 후 적절한 SQL을 만들어 데이터베이스를 조회
  • 방언(Dialect)만 변경하면 JPQL을 수정하지 않고 자연스럽게 DB 변경 가능

기본적인 문법은 SQL과 유사하다!

📌 JPQL은 엔티티 객체를 대상으로 쿼리를 질의하고, SQL은 데이터베이스 테이블을 대상으로 쿼리를 질의한다.


✔️ JPQL 문법

select_문 :: = 
    select_절
    from_절
    [where_절]
    [groupby_절]
    [having_절]
    [orderby_절]
update_문 :: = update_절 [where_절]
delete_문 :: = delete_절 [where_절]
  • from 절에 들어가는 것은 객체이다
    ➡️select m from Member m where m.age > 8
  • 엔티티와 속성은 대소문자를 구분
    ➡️ 예를 들면, Member 엔티티와 username 필드
  • JPQL 키워드는 대소문자 구분 안함
    ➡️ SELECT, FROM, where
  • 엔티티 이름을 사용한다. 테이블 이름이 아니다
    ➡️ 엔티티명 Member
  • 별칭은 필수이다(AS는 생략 가능하다)
    ➡️ Member 의 별칭 m

✔️ TypeQuery, Query

JPQL 실행할 시 쿼리 객체 생성이 필요하다.

1. TypeQuery : 반환할 타입을 명확하게 지정할 수 있을 경우

TypedQuery<Member> query = 
    em.createQuery("SELECT m FROM Member m", Member.class); // 반환이 명확
 
List<Member> resultList = query.getResultList();
for (Member member : resultList) {
    System.out.println("member = " + member);
}

2. Query : 반환 타입을 명확하게 지정할 수 없을 경우

또는 여러 엔티티나 컬럼을 선택할 경우(반환 타입이 명확하지 않을 경우) 사용한다.

Query query = 
    em.createQuery("SELECT m.username, m.age FROM Member m");
 
List resultList = query.getResultList();
for (Object o : resultList) {
    Object[] result = (Object[]) o; // 결과가 둘 이상일 경우 Object[]
    System.out.println("username = " + result[0]);
    System.out.println("age = " + result[1]);
}

✔️ 결과 조회

1. query.getResultList() : 결과를 예제로 반환

  • 결과가 없을 경우 빈 컬렉션 반환

2. query.getSingleResult() : 결과가 정확히 하나일 때 사용

  • 결과가 없으면 javax.persistence.NoResultException 예외 발생
  • 결과가 1보다 많으면 javax.persistence.NonUniqueResultException 예외 발생

✔️ 파라미터 바인딩

1. 이름 기준 파라미터(Named parameters)

String usernameParam = "User1";
 
TypedQuery<Member> query = 
    em.createQuery("SELECT m FROM Member m where m.username = :username", Member.class); // 파라미터 정의
query.setParameter("username", usernameParam); // 파라미터 바인딩
List<Member> resultList = query.getResultList();
 
// 아래와 같이 작성 가능(메소드 체인)
List<Member> members = 
    em.createQuery("SELECT m FROM Member m where m.username = :username", Member.class)
    .setParameter("username", usernameParam)
    .getResultList();
  • 파라미터를 이름으로 구분
  • : 사용
  • 더 명확한 방식

2. 위치 기준 파라미터(Positional parameters)

List<Member> member =
    em.createQuery("SELECT m FROM Member m where m.username = ?1", Member.class)
    .setParameter(1, usernameParam)
    .getResultList();
  • ? 다음에 위치 값을 지정

📌 참고 자료

profile
Backend Developer

0개의 댓글