Java / Spring
JPQL (JPQL기본기능, 결과조회 API, 쿼리의종류, 파라미터 바인딩) 본문
JPQL 이란? (Java Persistence Query Language)
- JPA 는 SQL을 추상화한 JPQL 이라는 객체 지향 쿼리 언어를 제공 한다.
- SQL과 문법이 유사하고, SELECT, FROM, WHERE, GROUP BY, HAVIG, JOIN 지원
- JPQL은 엔티티 객체를 대상으로 쿼리
- SQL은 데이터베이스(DB) 테이블을 대상으로 쿼리
try {
List<Member> result = em.createQuery(
"select m From Member m where m.username like '%kim%", Member.class
).getResultList();
tx.commit();
}
- 위의 JPQL 문법 중 Member 는 @Entity 속성이다.
- Member 는 객체를 뜻하기 때문에 클래스에 선언된 대로 대소문자를 구분해야 한다. 마찬가지로 m.age 또한 클래스내의 변수를 초기화 한 것과 같이 대소문자를 구분해야 한다.
- JPQL 키워드(select, from, where)는 대소문자 구분 하지 않아도 된다.
- from 의 대상은 엔티티 이름을 사용한다 (Table 이름이 아니다)
- 별칭은 필수(m) (as는 생략 가능)
** 쿼리의 종류 (TypeQuery / Query)
- TypeQuery 는 반환 타입이 명확할 때 사용
- Query 는 반환 타입이 명확하지 않을 때 사용
(사용 예 ↓)
Member member = new Member();
member.setUsername("member1");
member.setAge(10);
em.persist(member);
// 타입 쿼리 사용 (반환타입이 명확할 때)
TypedQuery<Member> query1 = em.createQuery("select m.username from Member m", Member.class);// Member.class : 타입 정보
// 쿼리 사용 (반환타입이 명확하지 않을 때) = query 문에 String(username) 타입과 int(age) 타입이 동시에 사용될 때
Query query2 = em.createQuery("select m.username, m.age from Member m", Member.class);// Member.class : 타입 정보
*** 파라미터 바인딩
- 쿼리에 작성되는 특정 속성을 매개변수로 매핑 하는 것을 말한다.
- 쿼리에 매개변수를 매핑하는 방식에는 이름을 기준으로 하는 방식과 위치를 기준으로 하는 방식이 있다.
+ code Ex1) 이름 기반 바인딩
TypedQuery<Member> query1 = em.createQuery("select m from Member m where m.username = :username", Member.class);
query1.setParameter("username", "member1"); // 이름 기반 바인딩
- 이름 기준 바인딩은 =: (연산자) 를 사용
- 메서드 체이닝을 사용할 수 있다.
+ code Ex2 ) 위치 기반 바인딩
TypedQuery<Member> query1 = em.createQuery("select m from Member m where m.username = :? 1", Member.class);
query1.setParameter(1, "member1"); // 위치 기반 바인딩
- 위치 기준 바인딩은 =? (연산자) 를 사용
- 이름 기반 바인딩과 마찬가지로 메서드 체이닝 사용 가능
정리
- 매개변수를 바인딩 할때는 이름 기반 바인딩을 사용 권장
- 위치 기반 바인딩을 사용 하면 중간에 새로운 매개변수를 추가하는 경우, 순서가 밀리기 때문이다.
- 또한, 숫자를 통해 어떤 위치의 매개변수가 무엇을 의미하는지 파악이 어렵다.
- 가독성이 떨어지고, 유지보수성도 떨어진다.
-------------------------------------------------------------------------------------------------------------------------------------------------------
참조 1. Criteria (사용 권장 X)
CriteriaBulder() 생성 ( JAVA 표준 문법) - 특별한 상황 아닐 시 사용 권장하지 않는다
try {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Member> query = cb.createQuery(Member.class);
Root<Member> m = query.from(Member.class);
CriteriaQuery<Member> cq = query.select(m).where(cb.equal(m.get("username"), "kim"));
em.createQuery(cq).getResultList();
tx.commit();
}
** Criteria 코드의 장점 :
- 동적 쿼리 적용에 유리하다.
- 오타 시 컴파일 오류
- 문자가 아닌 자바 코드로 JPQL 작성 가능
** Criteria 코드의 단점 :
- 코드 복잡성으로 인해 유지보수성 & 실용성 ↓
- Criteria 대신 QueryDSL 사용 권장
참조 2. QueryDSL (오픈소스 라이브러리)
- 하이버네이트 쿼리 언어의 쿼리를 타입에 안전하게 생성 및 관리해주는 프레임 워크
- QueryDSL 은 정적 타입을 이용하여 SQL 과 같은 쿼리를 생성할 수 있게 해준다.
- 복잡한 쿼리, 동적 쿼리 구현에 있어 한계가 존재한다.
- QueryDSL 은 자바 코드로 SQL 문을 작성할 수 있어 컴파일 시에 오류를 발생하여 잘못된 쿼리가 실행되는 것을 방지할 수 있다.
참조 3. NativeQuery
try {
Member member = new Member();
member.setUsername("member1");
em.persist(member);
List<Member> resultList = em.createNativeQuery("select MEMBER_ID, city, street, zipcode, USERNAME from MEMBER", Member.class)
.getResultList(); // em.createNativeQuery 이 시점에 flush() 동작
for (Member member1 : resultList) {
System.out.println("member1 = " + member1);
}
tx.commit();
NativeQuery 를 하는 시점에 flush() 동작
'Spring > Spring Data JPA' 카테고리의 다른 글
EntityManager & EntityManagerFactory (0) | 2024.09.20 |
---|---|
JPQL(Named 쿼리) @NamedQuery (0) | 2024.05.09 |
값 타입 (+ 기본값, 임베디드, 불변객체 타입) (0) | 2024.05.08 |
영속성 전이 : CASCADE (+고아 객체) (0) | 2024.05.07 |
상속관계 매핑 (@InheritanceType.~) (0) | 2024.05.06 |