select m from Member as m where m.age > 18
-> Member : 엔티티속성, 대소문자 구분
java클래스는 대소문자를 구분하기 때문
엔티티이름 사용, 테이블이름 아님
엔티티 이름을 @Entity(name = "mm")으로 수정시 jpql에서도 mm으로 써야 한다.
-> jpql 키워드 : select, from, where 대소문자 구분 안함
select m
count(m) //회원 수
sum(m.age) //나이 합
avg(m.age) //평균 나이
max(m.age) //최대 나이
min(m.age) //최소 나이
from Member m
-TypeQuery : 반환타입이 명확할 때 사용
-Query : 반환값이 명확하지 않을 때 사용
TypeQuery query = em.createQuery("select m from member m", Member.class);
Query query = em.createQuery("select m.username,m.age from Member m");
package com.codingbox.jpql;
import java.util.List;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.EntityTransaction;
import jakarta.persistence.Persistence;
import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery;
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf
= Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Member member = new Member();
member.setUsername("member1");
em.persist(member);
//두번째 파라미터로 응답 클래스에 대한 type정보를 줄 수 있다.
TypedQuery<Member> query = em.createQuery("select m from Member m",Member.class);
//타입정보가 String.class로 반환타입이 명확할 때
TypedQuery<String> query2 = em.createQuery("select m.username from Member m",String.class);
//String, int : 이렇게 반환타입이 명확하지 않을 때
Query query3 = em.createQuery("select m.username,m.age from Member m "); //이건 파라미터 하나로 받아오는 거
TypedQuery<Member> query4 = em.createQuery("select m from Member m",Member.class);
List<Member> resultList = query4.getResultList();
for(Member m : resultList) {
System.out.println("m = " + m );
}
TypedQuery<Member> query5 = em.createQuery("select m from Member where m.id", Member.class); //pk값으로 조회했으니까 한건만 나옴
Member result = query5.getSingleResult();
System.out.println("result : " +result);
tx.commit();
em.close();
emf.close();
}
}
예시코드를 가져와 봤다. select m from Member m이 쿼리문은 엔티티 전체를 말하지만
select m.username from Member m이 쿼리는 username만을 조회한다.
또한
Query query3 = em.createQuery("select m.username,m.age from Member m ");
TypedQuery query4 = em.createQuery("select m from Member m",Member.class);
이 두 코드를 분석하면 query를 통해 가져오면 반환타입이 명확하지 않기에 파라미터를 하나만 가져온다. 하지만 TypedQuery같은 경우 반환타입이 명확하여 파라미터를 2개 취한다.
query.getResultList() : 결과가 하나 이상일 때, 리스트 반환
-> 결과가 없으면 빈 리스트 반환
-> 빈 collection이 반환되기 때문에 NullPointException에 대한 걱정은 안해도 된다.
query.getSingleResult() : 결과가 정확히 하나(조심), 단일 객체 반환
-> 결과가 없으면 : NoResultException
-> 결과가 둘 이상이면 : NonUniqueResultException
//파라미터 바인딩
TypedQuery<Member> query = em.createQuery("select m from Member m where m.username = :username",Member.class);
query.setParameter("username", "member1");
Member result = query.getSingleResult();
System.out.println("result : " + result.getUsername());
System.out.println("----------------------------------------");
//파라미터 바인딩 - 메시지 체인방법
Member result2 = em.createQuery("select m from Member m where m.username = :username",Member.class)
.setParameter("username", "member1")
.getSingleResult();
query.setParameter(1,usernameParam);
package com.codingbox.jpql;
import java.util.List;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.EntityTransaction;
import jakarta.persistence.Persistence;
import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery;
public class JpaMain5 {
public static void main(String[] args) {
EntityManagerFactory emf
= Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
// Member member = new Member();
// member.setUsername("memeber1");
// member.setAge(10);
// em.persist(member);
em.flush();
em.clear(); //이 두 코드를 지난 후 준영속 상태
for(int i = 1; i <= 100; i++) {
Member member = new Member();
member.setUsername("member" +i);
member.setAge(i);
em.persist(member);
}
//페이징 처리
String jpql = "select m from Member m order by m.age desc";
List<Member> resultList= em.createQuery(jpql,Member.class)
.setFirstResult(10)
.setMaxResults(20)
.getResultList();
System.out.println("result.size = " + resultList.size());
for(Member m : resultList) {
System.out.println("m : " + m.toString());
}
tx.commit();
em.close();
emf.close();
}
}
원래대로라면 100개를 가져와야 하는데 20개 밖에 가져오지 않는다. setMaxResults(20)을 통해 최대 20개의 정보를 가져온다.
문법이 객체 스타일로 나간다.
내부조인
-> select m from Member m(inner) join m.team t
외부조인
-> select m from Member m left (outer) join m.team t