✏️ [JPQL] JPQL 기본 문법

박상민·2023년 10월 28일
0

JPA

목록 보기
15/24
post-thumbnail

⭐️ JPQL

JPQL

  • JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어 제공
  • SQL과 문법 유사, SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN 지원
  • JPQL은 엔티티 객체를 대상으로 쿼리
  • JPQL을 한마디로 정의하면 객체 지향 SQL
  • SQL은 데이터베이스 테이블을 대상으로 쿼리
    • ex)
//검색
String jpql= "select m From Member m where m.name like '%hello%'";

  List<Member> result = em.createQuery(jpql, Member.class).getResultList();
  

JPQL은 객체지향 쿼리 언어이다. 따라서 테이블을 대상으로 쿼리하는 것이 아니라 엔티티 객체를 대상으로 쿼리한다.
또한, JPQL은 SQL을 추상화해서 특정데이터베이스 SQL에 의존하지 않는다.
JPQL은 맵핑 정보랑 방언이 조합 돼서 SQL로 변환이 되어서 실행된다.

select
  m.id as id,
  m.age as age,
  m.USERNAME as USERNAME,
  m.TEAM_ID as TEAM_ID
from
  Member m
where
  m.age>18

📌 앞으로 설명에 사용할 모델 구조


위 사진은 앞으로 설명에 사용할 모델의 구조를 나타냈다. 계속 JPQL에 대한 글을 작성할텐데 모두 이 구조를 기반으로 설명한다.
Member, Team, Order 등이 있고 회원이 상품을 주문한다. 또한, 오더에는 밸류 타입인 Adress를 만들어서 연결했다.

📌 JPQL 문법

  • from절에 들어가는 것은 객체다!

    • select m from Member m where m.age > 8
  • 엔티티와 속성은 대소문자를 구분

    • 예를 들면, Member 엔티티와 username 필드
  • JPQL 키워드는 대소문자 구분 안함

    • SELECT, FROM, where
  • 엔티티 이름을 사용한다. 테이블 이름이 아니다

    • 엔티티명이 MM이라면 MM을 사용한다.
  • 별칭은 필수이다. (as는 생략 가능)

    • ex) Member의 별칭 m - select m from Member as m

📌 TypeQuery, Query

  • TypeQuery: 반환 타입이 명확할 때 사용

  • Query: 반환 타입이 명확하지 않을 때 사용


TypedQuery<Member> query = 
	em.createQuery("SELECT m FROM Member m", Member.class); 
//두번째에 작성한 Member.class는 반환 타입이다.

이 코드는 Member.class라고 반환 타입을 명확하게 나타내주었다. 반환 타입을 명시했기에 TypeQuery가 사용되었다.

그러나 아래 코드의 경우는 다르다.

Query query = 
	em.createQuery("SELECT m.username, m.age from Member m");

Member의 username, age 정보를 가져오라는 쿼리이다. 이때 username은 String이고 age는 int이다.
2개의 타입이 존재하기에 타입 정보를 명시할 수 없다. 이때는 Query가 사용된다.

📌 결과 조회 API

query.getResultList(): 결과가 하나 이상일 때, 리스트 반환

List<Member> resultList = 
		em.createQuery("SELECT m FROM Member m", Member.class)
           .getResultList();
  • 결과가 없으면 빈 리스트 반환: NullPointException을 걱정하지 않아도 된다.

query.getSingleResult(): 결과가 정확히 하나, 단일 객체 반환

Member member = 
		em.createQuery("SELECT m FROM Member m where m.id = 10", Member.class)
			.getSingleResult();
  • 결과가 없으면: javax.persistence.NoResultException
  • 둘 이상이면: javax.persistence.NonUniqueResultException

📌 파라미터 바인딩

이름 기준으로 바인딩

em.createQuery("select m from Member m where m.username = :username", Member.class)
                    .setParameter("username", "member1")
                    .getSingleResult();

위치 기준으로 바인딩

em.createQuery("select m from Member m where m.username = ?1", Member.class)
                    .setParameter(1, "member1")
                    .getSingleResult();

위치 기반 바인딩은 사용하지 말자!
만약 1, 2, 3 순서로 데이터가 있는데 중간에 하나가 끼어든다면? 끼어든 데이터 뒤에 있는 데이터들은 위치가 바뀌고 오류의 원인이 될 수 있다.

파라미터 바인딩은 이름 기준으로 사용하자.


출처
자바 ORM 표준 JPA 프로그래밍 강의
게시글 속 자료는 모두 위 강의 속 자료를 사용했습니다.

profile
스프링 백엔드를 공부중인 대학생입니다!

0개의 댓글