[JPA] JPQL이란? with.기본 문법

지니·2025년 4월 1일
1

JPA

목록 보기
4/4
post-thumbnail

1. JPQL 개요


1-1. JPQL이란?

JPQL은 엔터티 객체를 중심으로 개발할 수 있는 객체 지향 쿼리로 SQL문보다 간결하며 특정 DBMS에 의존하지 않는다. dialect를 통해 사용자의 DBMS에 맞게 SQL을 실행해준다.

1-2. JPQL을 사용하는 이유

  • JPA는 복잡한 관계를 표현하는데 한계가 있다. 이러한 점을 보완하는 방법이 JPQL이다.
  • JPA에서는 JPQL을 기반으로 한 다양한 쿼리 문법을 지원한다. 예를 들어, JPQL, JPA Criteria, QueryDSL 등이 있다.
  • 이러한 다양한 문법은 JPA로 모든 쿼리를 커버할 수 없기 때문이다. 그리고, 이 중심에 JPQL이 있다.
  • ANSI 표준에서 지원하는 쿼리 명령문을 모두 제공한다.
  • SQL을 추상화 한 것이기 때문에 특정 DB에 종속적이지 않다. 그렇기 때문에 DB 사용이 자유롭다.

2. JPQL의 기본 문법


2-1. JPQL 사용 방법

1. JPQL문을 작성한다.

String jpql = "SELECT m FROM Menu as m WHERE m.menuCode = 8";
  • JPQL을 작성할 때 반드시 엔티티는 별칭을 사용해야 한다.
  • JPQL은 엔티티를 사용하기 위해서 작성하는 것이다. 그렇기 때문에 테이블명이 아닌 엔티티명으로 작성해야 한다.

2. JPQL은 EntityManger의 createQuery() 메소드를 통해서 쿼리 객체로 만든다.

entityManager.createQuery(만들고자 하는 JPQL문);

3. 쿼리 타입에는 반환할 타입 여부에 따라 2가지 타입으로 나뉜다.

  • TypedQuery : 반환 타입을 명확하게 지정할 때 사용한다.
  • Query : 반환 타입을 명확하게 지정할 수 없는 경우에 사용하며 Object나 Object[]가 반환된다.

4. 쿼리를 실행하고 DB를 조회하는 방법에는 getSingleResult()getResultList()가 있다.

  • getSingleResult() : 결과가 정확히 1개의 행인 경우 사용하며 없거나 많으면 예외가 발생한다.
  • getResultList() : 결과가 2행 이상일 경우 사용하며 컬렉션을 반환한다. 결과가 없으면 빈 컬렉션을 반환한다.

2-2. 조회 예시

2-2-1. 타입이 지정되어 있는 경우

  • TypedQuery<자료형>로 지정해서 사용하고 있다.
  • 결과가 정확히 한 행인 경우에는 getSingleResult()를 사용하고, 여러 행이 나오는 경우에는 getResultList() 를 사용한다.
// 1. 지정된 타입으로 menuName을 가져오는 경우
public String selectSingleMenuByTypedQuery() {
    // menuName만 가져오는 경우
    String jpql = "SELECT m.menuName FROM Section01Menu as m WHERE m.menuCode = 8";
    TypedQuery<String> query = entityManager
    .createQuery(jpql, String.class);
    String resultMenuName = query.getSingleResult();
    return resultMenuName;
}

// 2. menu 엔티티의 모든 필드값을 가져오기
public Menu selectSingleRowMenuByTypedQuery() {
	// menu라는 엔티티 그 자체를 조회한다는 의미임
    String jpql = "SELECT m FROM Section01Menu as m WHERE m.menuCode = 8";
    TypedQuery<Menu> query = entityManager.createQuery(jpql, Menu.class);
    Menu resultMenu = query.getSingleResult();
    return resultMenu;
 }
 
// 3. 여러 행을 가져오기 : getResultList()를 사용
public List<Menu> selectMultiRowMenuByTypedQuery() {
	// 모든 행을 가져오기
	String jpql = "SELECT m FROM Section01Menu m";
    TypedQuery<Menu> query = entityManager.createQuery(jpql, Menu.class);
    List<Menu> menuList = query.getResultList();
    return menuList;
}

2-2-2. 타입이 지정되지 않은 경우

  • 타입이 지정되어 있지 않아, Object 타입을 이용해 반환 값을 받고 있다.
public Object selectSingleMenuByQuery() {
	String jpql = "SELECT m.menuName FROM Section01Menu as m WHERE m.menuCode = 8";
    Query query = entityManager.createQuery(jpql);
    Object resultMenuName = query.getSingleResult();
    return resultMenuName;
}

2-2-3. Distinct, in, like 사용해서 조회하기

간단하게 각각의 역할을 설명하면

  • DISTINCT : 중복 없이 조회
  • IN : in안에 잇는 값들을 조회
  • LIKE : %로 둘러싸인 글자가 포함되어 있는 메뉴를 조회
/* 1. tbl_menu의 categoryCode 중복 없이 조회 */
public List<Integer> selectUsingDistinct(){
	String jpql = "SELECT DISTINCT m.categoryCode FROM Section01Menu m";
    TypedQuery<Integer> query = entityManager.createQuery(jpql, Integer.class);

    List<Integer> menuCategory = query.getResultList();
    return menuCategory;
}

/* 2. tbl_menu의 11,12 카테고리 코드를 가진 메뉴 목록 조회 */
public List<Menu> selectUsingIn(){
	String jpql = "SELECT m FROM Section01Menu m WHERE m.categoryCode in(11,12) ";
    TypedQuery<Menu> query = entityManager.createQuery(jpql, Menu.class);

    List<Menu> menuList = query.getResultList();
    return menuList;
}

/* 3. tbl_menu의 "마늘"이 메뉴명에 포함 된 메뉴 목록 조회*/
public List<Menu> selectUsingLike(){
	String jpql = "SELECT m FROM Section01Menu m WHERE m.menuName like '%마늘%'";

    List<Menu> menuList = entityManager.createQuery(jpql, Menu.class).getResultList();
    return menuList;
}

0개의 댓글