JPQL이란?
엔티티 객체를 조회하는 객체지향 쿼리로 테이블을 대상으로 쿼리하는 것이 아니라 엔티티 객체를 대상으로 쿼리한다. 문법은 SQL과 유사하며 간결하다. JPQL은 최종적으로 SQL로 변환된다.
JPQL은 SQL을 추상화해서 특정 데이터베이스에 의존하지 않는다는 특징이 있다. 데이터베이스 hibernate.dialect(방언)만 변경하면 JPQL을 수정하지 않아도 데이터베이스를 변경할 수 있다.
JPQL 특징
- 테이블이 아닌 객체를 검색하는 객체지향 쿼리이다.
- SQL을 추상화 했기 때문에 특정 DBMS 벤더에 종속적이지 않다.
- JPA는 JPQL을 분석하여 SQL을 생성한 후 DB에서 조회한다.
** 기본 문법 : String data = "select j from Jikwon as m where j.name = '한국인'";
JPQL은 ANSI SQL과 문법이 유사하지만 몇 가지 다른 점이 있다.
1) 대소문자 구분
엔티티와 속성은 대소문자를 구분한다. 엔티티 이름인 Jikwon , 그리고 Jikwon의 속성 name은 대소문자를 구분해줘야 한다.
반면에 SELECT, FROM, AS 같은 JPQL 키워드는 대소문자를 구분하지 않아도 된다.
2) 엔티티 이름
JPQL에서 사용한 Jikwon은 클래스 이름이 아닌 엔티티 이름이다. 엔티티 이름은 @Entity(name="abcd")로 설정 가능하다.
name 속성을 생략하면 기본 값으로 클래스 이름을 사용한다.
3) 별칭
JPQL에서 엔티티의 별칭은 필수적으로 명시해야 한다. 별칭을 명시하는 AS 키워드는 생략할 수 있다.
JPQL 적용 간단한 예) --------------------------------------------
@Entity
@Table(name = "sangdata")
@Data
public class ProductVo {
@Id
@Column(name="code")
private int code;
@Column(name="sang", nullable = false, length = 20)
private String sang;
@Column
private int su;
@Column
private int dan;
}
public interface ProductCrudRepository extends JpaRepository<ProductVo, Integer>{
@Query(value = "select p from ProductVo as p") // Entity명은 대문자 (나머진 구분 안함)
List<ProductVo> findAllData();
// 1) where 조건
//@Query(value = "select p from ProductVo as p where p.code=:code")
// 2) where 조건 - ? 연산을 사용할 수 있다.
@Query(value = "select p from ProductVo as p where p.code=?1") // 매개변수 1개
ProductVo findByCode(int code);
// 3) where 조건이 복수인 경우 - ? 연산을 사용할 수 있다.
@Query(value = "select p from ProductVo as p where p.code=?1 or p.sang=?2") // 매개변수 2개
List<ProductVo> findByData(int code, String sang);
}
___ Service 클래스 에서 _________
private void selectData() {
System.out.println("JPQL 사용 : interface ProductCrudRepository에 추상 메소드 작성 후 사용");
System.out.println("--전체 레코드 읽기 --");
List<ProductVo> list2 = (List<ProductVo>)repository.findAllData();
for(ProductVo vo_ql:list2) {
System.out.println(vo_ql.getCode() + " " + vo_ql.getSang() + " " + vo_ql.getSu() + " " + vo_ql.getDan() + " ");
}
System.out.println("--특정 레코드 한 개 읽기 --");
ProductVo vo_ql2 = repository.findByCode(2);
System.out.println(vo_ql2.getCode() + " " + vo_ql2.getSang() + " " + vo_ql2.getSu() + " " + vo_ql2.getDan() + " ");
System.out.println("--특정 레코드 여러 개 읽기 --");
List<ProductVo> list3 = (List<ProductVo>)repository.findByData(2, "새우깡");
for(ProductVo vo_ql3:list3) {
System.out.println(vo_ql3.getCode() + " " + vo_ql3.getSang() + " " + vo_ql3.getSu() + " " + vo_ql3.getDan() + " ");
}
}
참조 페이지
[JPA] @Query, 직접 쿼리 작성 https://jforj.tistory.com/90
[JPA] Select Query https://hgko1207.github.io/2021/06/19/spring-jpa-1/
JPA Query https://joojimin.tistory.com/56
[JPA] JPQL Query 정리 https://data-make.tistory.com/614
객체 지향 쿼리 소개, JPQL https://steady-coding.tistory.com/582