JPQL
QueryDSL
JPA Criteria
네이티브 SQL
JDBC API 직접 사용
MyBatis
SpringJdbcTemplate
단순한 조회 : EntityManager.find()
예시) 나이가 18살 이상인 회원을 모두 검색하고 싶다면?
Java Persistence Query Language
- JPA를 사용하면 엔티티 객체를 중심으로 개발
- 문제는 검색 쿼리
- 검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 검색
- 모든 DB데이터를 객체로 변환해서 검색하는 것은 불가능
- JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어를 제공
- SQL 문법이 유사, select / from / where / group by / having / join 지원
- JPQL 엔티티 객체를 대상으로 쿼리를 작성
- SQL은 데이터베이스 테이블을 대상으로 쿼리를 작성
- JPQL을 한 마디로 정의하면 '객체 지향 SQL'
- 대소문자 구분
- 엔티티와 속성은 대소문자 구분한다.
- JPQL 키워드는 구분하지 않는다.
- 엔티티 이름
- 테이블명 대신 엔티티명을 사용한다.
- @Entity(name = "...") // 엔티티명 지정하는 방법
- 엔티티명을 지정하지 않을 시에는 클래스명을 기본 값으로 사용 (추천하는 방법)
- 별칭은 필수
- JPQL은 별칭 필수
- AS는 생략 가능
- select m from Member as m where m.age > 18
- Member : 엔티티 속성, 대소문자 구분
- java 클래스는 대소문자를 구분하기 때문
- 엔티티 이름 사용, 테이블 이름이 아니다.
- 엔티티 이름을 @Entity(name = "mm")으로 수정 시, JPQL에서도 mm으로 써야 한다. (하지만 이렇게 쓰지 않음)
- JPQL 키워드 : select, from, where 대소문자 구분 안 함
select count(m), // 회원수 sum(m.age), // 나이 합 avg(m.age), // 평균 나이 max(m.age), // 최대 나이 min(m.age) // 최소 나이 from Member m
- group by, having
- order by
- TypeQuery : 반환 타입이 명확할 때 사용
TypeQuery<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.getResultList() : 결과가 하나 이상일 때, 리스트 반환
✔️ 결과가 없으면 빈 리스트 반환
✔️ 빈 collection이 반환되기 때문에 NullPointException에 대한 걱정은 안 해도 된다.
- query.getSingleResult() : 결과가 정확히 하나(조심!), 단일 객체 반환
✔️ 결과가 없으면 : NoResultException
✔️ 결과가 둘 이상이면 : NoUniqueResultException
- 이름 기준
select m from Member m where m.username = :username query.setParameter("username", usernameParam);
- 위치 기준 (쓰지 말 것!)
select m from Member m where m.username = ?1 query.setParameter(1, usernameParam);
- select 절에 조회할 대상을 지정하는 것
- 프로젝션 대상 : 엔티티, 임베디드 타입, 스칼라 타입 (숫자, 문자 등 기본 데이터 타입)
- select m from Member m : Member 엔티티 조회
- select m.team from Member m : Member와 관련된 team을 가지고 온다.
- select m.address from Member m : 임베디드 타입을 가지고 온다.
- select m.username, m.age from Member m : 스칼라 타입 프로젝트
** JpaMain04
- JPA는 페이지를 다음 두 API로 추상화
- setFirstResult(int startPoint) : 조회 시작 위치 (0부터 시작)
- setMaxResults(int maxResult) : 조회할 데이터 수
-> 몇 번째부터 몇 건을 가지고 올래?
- 문법이 객체 스타일로 나간다.
내부조인
elect m from Member m (inner) join m.team t
외부조인
select m from Member m left (outer) join m.team t
- From절의 서브쿼리는 현재 JPQL에서는 불가능하다. 조인으로 풀 수 있으면 풀어서 해결