
JPA를 사용하면 엔티티 객체를 중심으로 개발하기 때문에 검색을 할 때도
테이블이 아닌 엔티티 객체를 대상으로 검색한다.
JPQL은 데이터를 최소화해서 검색해야하는 문제점을 해결할 수 있다.
객체 지향 쿼리 언어를 제공한다.
JPQL을 한마디로 정의하면 객체 지향 SQL이라고 말할 수 있다.
JPQL은 SQL을 추상화해서 특정 데이터베이스에 의존하지 않는다. 그리고 데이터베이스 방언만 변경하면 JPQL을 수정하지 않아도 자연스럽게 데이터베이스를 변경할 수 있다.
전체구조는 SQL(SELECT, UPDATE, DELETE)과 비슷하고, INSERT 문은 em.persist() 메소드를 사용하면 되므로 따로 없다.
"SELECT m FROM Member m where m.username = 'kim'"
TypeQuery : 반환 타입이 명확할 때 사용
em.createQuery("SELECT m FROM Member m", Member.class);
Query : 반환 타입이 명확하지 않을 때 사용
em.createQuery("SELECT m.username, m.age FROM Member m");
query.getResultList() : 여러개의 결과를 반환할 때 사용한다. 만약 결과가 없다면 빈 컬렉션을 반환한다.
query.getSingleResult() : 결과가 없거나, 결과가 1개보다 많으면 예외가 발생하므로 정확히 하나일 때 사용한다.
바인딩 방식을 사용하면 파라미터의 값이 달라도 같은 쿼리로 인식해서 파싱한 결과를 다시 사용할 수 있다. 데이터베이스 내부에서 실행한 SQL을 파싱해서 사용하는데 같은 쿼리는 항상 파싱의 결과를 재사용 할 수 있다.
결과적으로 데이터베이스 모두 해당 쿼리의 파싱 결과를 재사용할 수 있기 때문에 선택이 아닌 필수이다!
원하는 객체를 바로 조회한 것인데, 조회한 엔티티는 영속성 컨텍스트에서 관리된다.
SELECT m FORM Member m
SELECT m.team FROM Member m
임베디드 타입은 엔티티와 거의 비슷하게 사용하며, 임베디드 타입은 조회의 시작점이 될 수 없다는 제약이 있다.
select o.address from Order o
숫자, 문자 날짜와 같은 기본 데이터 타입들이다.
List<String> username = em.createQuery("select username from Member m", String.class).getResultList();
여러 값을 선택하면 TypeQuery를 사용할 수 없다. 필요한 데이터들만 선택해서 조회해야 할 때 사용한다.
패키지 명을 포함한 전체 클래스 명을 입력해야 하며, 순서와 타입이 일치하는 생성자가 필요하다.
각각의 데이터베이스의 방언으로 알아서 해준다.
setFirstResult(int startPostion): 조회 시작 위치
setMaxResult(int maxResult) : 조회할 데이터 수