JPA에 대해 알아보자 : 10장 객체지향 쿼리 언어

ParkIsComing·2023년 9월 18일

Spring

목록 보기
13/21
post-thumbnail

책 [자바 ORM 표준 JPA 프로그래밍]을 참고하여 작성하였습니다.

JPQL

  • 테이블이 아닌 객체를 대상으로 검색하는 객체지향 쿼리
  • SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않는다.
  • JPQL을 사용하면 JPA는 JPQL을 분석하여 적절한 SQL을 만들어 DB를 조회한다.
  • Criteria Query : JPQL을 편하게 작성하도록 도와주는 API, 빌더 클래스 모음
  • 네이티브 SQL : JPA에서 JPQL 대신 직접 SQL을 사용할 수 있다.
  • QueryDSL : Critieria Query처럼 JPQL을 편하게 작성하도록 도와주는 빌더 클래스

JPQL 사용법

기본 문법

  • SQL과 비슷하게 SELECT, UPDATE, DELETE 가능
  • 저장할 때는 EntityManager.persist() 메소드를 사용하면 되므로 INSERT 문은 없음
  • 엔티티와 속성은 대소문자 구분하나, JPQL 키워드는 대소문자 구분x
    -별칭을 필수로 사용해야 함.(아래 예시의 from Member as m처럼)

예시

String jpql = "select m from Member as m where m.username = 'kim'";  //Member는 클래스명이 아니라 엔티티명
List<Member> resultList = em.createQuery(jpql, Member.class).getResultList();

TypeQuery, Query

  • 작성한 JPQL을 실행하려면 TypeQuery나 Query를 이용해 쿼리 객체를 만들어야 한다.
  • 반환 타입을 명확하게 지정할 수 있으면 TypeQuery, 아니면 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.printlin("age = " + result[1]);
}

결과 조회

  • query.getResultList() : 결과를 예제로 반환(없으면 빈 컬렉션 반환)
  • query.getSingleResutl() : 결과가 정확히 하나일 때 사용(아니면 예외발생)

파라미터 바인딩

  • JDBC는 위치 기준 파라미터 바인딩 & 이름 기준 파라미터 바인딩 제공
  • 이름 기준 파라미터 바인딩이 더 명확
  • 파라미터 바인딩 방식을 사용하지 않으면 SQL 인젝션 공격을 당할 수 있으며, 파라미터 바인딩 방식을 사용하면 파라미터 값이 달라도 같은 쿼리로 인식해서 JPA는 JPQL을 SQL로 파싱한 결과를 재사용하기 때문에 성능면에서도 낫다.
    • 이름 기준 파라미터 바인딩
String usernameParam = "User1";
TypeQuery<Member> query = em.createQuery("SELECT m FROM Member m where m.username = :username", Member.class);
  • 위치 기준 파라미터 바인딩
    List<Member> members = em.CreateQuery("SELECT m FROM Member m where m.username = ?1", Member.class)  //파라미터 위치값 1로 설정
    			.setParameter(1, usernameParam)
    			.getResultList();

Criteria Query

  • JPQL을 생성하는 빌더 클래스
  • 문자가 아닌 query.select(m).where(...)처럼 프로그래밍 코드로 JPQL 작성 가능
  • 장점
    • 컴파일 시점에 오류 발견 가능
    • IDE를 사용하면 코드 자동완성 지원
    • 동적 쿼리를 작성하기 편함
  • 단점
    • 사용하기 불편하고 복잡함

QueryDSL

  • Criteria처럼 JPQL 빌더 역할을 함
  • 코드 기반이면서 단순하고 사용하기 쉬움
  • 어노테이션 프로세서를 사용해서 쿼리 전용 클래스르 만들어야
    ex) QMember는 Member 엔티티를 기반으로 생성한 QueryDSL 쿼리 전용 클래스

네이티브 SQL

  • SQL을 직접 사용할 수 있도록 JPA에서 지원하는 기능
  • 단점
    • 특정 DB에 의존하는 SQL 작성(DB가 변경되면 SQL도 수정해야)
    • em.CreateNativeQuery()를 사용하면 된다.

0개의 댓글