JPA 객체지향 쿼리 언어(JPQL) - 기본 문법과 쿼리 API

2022. 7. 16. 19:06·공부/JPA
반응형

출처 : 자바 ORM 표준 JPA 프로그래밍 인프런 강의

 

JPA 게시글은 대부분 인프런의 김영한님의 강의인 '자바 ORM 표준 JPA 프로그래밍' 기반으로 내용을 정리했습니다.

 

기본 문법과 쿼리 API

  • JPQL? Java Persistence Query Language

 

JPQL

  • JPQL은 객체지향 쿼리 언어. 따라서 테이블이 아닌 엔티티 객체를 대상으로 쿼리한다.
  • JPQL은 SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않는다. → 방언
  • JPQL은 결국 SQL로 변환이 된다. (매핑 정보 + 방언 = SQL)

 

프로젝트 새로 생성 후

Member.class

@Entity
public class Member {

    @Id @GeneratedValue
    private Long id;
    private String username;
    private int age;

    @ManyToOne
    @JoinColumn(name = "TEAM_ID")
    private Team team;
    
    // getter/setter 생략
}

 

Team.class

@Entity
public class Team {

    @Id @GeneratedValue
    private Long id;

    private String name;

    @OneToMany(mappedBy = "team")
    private List<Member> members = new ArrayList<>();
    
    // getter/setter 생략
}

 

Address.class

@Embeddable
public class Address {

    private String city;
    private String street;
    private String zipcode;
    
    // getter/setter 생략
}

 

Order.class

@Entity
@Table(name = "ORDERS")
public class Order {

    @Id @GeneratedValue
    private Long id;
    private int orderAmount;

    @Embedded
    private Address address;
    
    @ManyToOne
    @JoinColumn(name="PRODUCT_ID")
    private Product product;
    
    // getteer/setter 생략
}

 

Product.class

@Entity
public class Product {

    @Id @GeneratedValue
    private Long id;
    private String name;
    private int price;
    private int stockAmount;
    
    // getter/setter 생략
}

 

 

JPQL 문법

  • 전체적으로 SQL과 유사하다.
select m from Member as m where m.age > 18
  • 엔티티와 속성은 대소문자를 구분한다.
  • JPQL 키워드(SELECT, FROM, where)는 대소문자를 구분하지 않는다.
  • 엔티티 이름 사용한다. MEMBER 테이블이 아니고 Member 엔티티 이름이다.
  • 별칭(m)은 필수이다. (as는 생략 가능함)

 

집합과 정렬

select
    COUNT(m), // 회원수
    SUM(m.age), // 나이, 합
    AVG(m.age), // 나이, 평균
    MAX(m.age), // 최대 나이
    MIN(m.age) // 최소 나이
from Member m
  • GROUP BY, HAVING
  • ORDER BY

다 사용이 가능하다.

 

TypeQuery, Query

  • TypeQuery : 반환 타입이 명확할 때 사용한다.
TypedQuery<Member> query = 
	em.createQuery("SELECT m FROM Member m", Member.class);
  • Query : 반환 타입이 명확하지 않을 때 사용한다.
Query query = 
	em.createQuery("SELECT m.username, m.age from Member m");
  • Query의 경우 m.username 만 가져왔을 때는 반환 타입을 String.class로 해줘도 되는데 위의 예제 코드에서는 m.age까지 가져오므로 타입을 특정할 수가 없기 때문에 Query를 사용한다.

 

결과 조회 API

  • query.getResultList() : 조회 결과가 하나 이상일 때 리스트로 반환해준다.
    • 결과가 없을 경우엔 빈 리스트를 반환한다.
TypedQuery<Member> query =
        em.createQuery("select m from Member m", Member.class);

List<Member> resultList = query.getResultList();
for (Member member1 : resultList) {
    System.out.println("member1 = " + member1);
}
  • query.getSingleResult() : 결과가 정확히 하나일 때 단일 객체로 반환해준다.
    • 결과가 없을 경우 : javax.persistence.NoResultException
    • 둘 이상이면 : javax.persistence.NonUniqueResultException
TypedQuery<Member> query =
        em.createQuery("select m from Member m", Member.class);

Member result = query.getSingleResult();
System.out.println("result = " + result);
  • 결과가 없을 경우엔 getResultList()처럼 null을 반환해주면 될 거 같은데 굳이 예외를 터트려준다. 그래서 결과가 없는 경우엔 따로 try~catch를 작성해줘야한다.
    • Spring Data JPA는 null이나 Optional로 반환해준다.

 

파라미터 바인딩 - 이름 기준, 위치 기준

  • 위치 기준은 쿼리는 위치에 따라 쿼리가 이상하게 작동될 수 있는 위험이 있어 사용하지 않는 것이 좋다.
  • 이름 기준으로 사용하자.
TypedQuery<Member> query =
        em.createQuery("select m from Member m where m.username = :username", Member.class);

query.setParameter("username", "member1");
Member singleResult =  query.getSingleResult();
System.out.println("singleResult = " + singleResult.getUsername());

 

이렇게 사용할 수도 있고 메서드 체이닝으로 사용할 수도 있다. 추천하는 방법은 메서드 체이닝 방법이다.

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

System.out.println("result = " + result.getUsername());

 

반응형
저작자표시 비영리 변경금지 (새창열림)
'공부/JPA' 카테고리의 다른 글
  • JPA 객체지향 쿼리 언어(JPQL) - 페이징 API
  • JPA 객체지향 쿼리 언어(JPQL) - 프로젝션(SELECT)
  • JPA 객체지향 쿼리 언어 - JPQL, QueryDSL 등 소개
  • JPA 값 타입 - 값 타입 컬렉션
데부한
데부한
어차피 할 거면 긍정적으로 하고 싶은 개발자
    반응형
  • 데부한
    동동이개발바닥
    데부한
  • 전체
    오늘
    어제
    • 분류 전체보기 (307)
      • 방통대 컴퓨터과학과 (27)
        • 잡담 (9)
        • 3학년1학기 (17)
      • 프로젝트 및 컨퍼런스 회고 (1)
        • 프로젝트 (4)
        • 한이음 프로젝트 (0)
        • 회고 (3)
      • 공부 (165)
        • Spring (37)
        • JPA (71)
        • 인프런 워밍업 클럽_BE (10)
        • Java (6)
        • React.js (27)
        • 넥사크로 (11)
        • 기타 (3)
      • 알고리즘 (85)
        • 알고리즘 유형 (10)
        • 알고리즘 풀이 (57)
        • SQL 풀이 (18)
      • 에러 해결 (13)
      • 잡담 (7)
        • 국비교육 (2)
        • 구매후기 (5)
        • 진짜 잡담 (0)
  • 블로그 메뉴

    • Github
    • Linkedin
    • 홈
    • 방명록
    • 글쓰기
    • 관리
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    코딩테스트
    자바스크립트
    에러해결
    스프링부트
    운영체제
    전자정부프레임워크
    QueryDSL
    프로그래머스
    react
    기출문제
    토이프로젝트
    프론트엔드
    Java
    oracle
    토비의스프링부트
    인프런
    RESTful
    IT
    egov
    JPA
    넥사크로
    MSA
    백준
    SpringBoot를 이용한 RESTful Web Service 개발
    알고리즘
    SQL
    springboot
    Spring
    개발자
    방통대
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
데부한
JPA 객체지향 쿼리 언어(JPQL) - 기본 문법과 쿼리 API
상단으로

티스토리툴바