JPQL은 SQL과는 달리 객체지향 모델에 대한 쿼리를 작성할 수 있는 쿼리 언어이다. 엔티티 객체와 그들 간의 관계를 사용하여 데이터를 검색, 수정, 조작할 수 있다. JPQL의 기본 구문은 SQL과 유사하지만, 엔티티 클래스와 필드를 기반으로 쿼리를 작성해야한다.
SELECT m FROM Member m WHERE m.name = :name
예를 들어, JPQL을 사용하여 엔티티 객체를 검색하려면 이렇게 작성할 수 있다. 이 쿼리는 Member
엔티티에서 name
필드를 조건으로 사용하여 엔티티를 검색하는것이다.
JPQL은 JPA와 함께 사용되며, 객체 지향 애플리케이션에서 데이터베이스와 상호작용할 때 유용하다.
아래에 설명할 코드는 내가 토이프로젝트때 사용했던 JPQL문법이다.
public List<ChatRoom> findChatRoomsByUser(User user) {
return em.createQuery("SELECT c FROM ChatRoom c WHERE c.fiter = :user", ChatRoom.class)
.setParameter("user", user)
.getResultList();
}
실제로 Spring에서 이렇게 사용이 가능한데, ChatRoom
이라는 엔티티에서 매개변수로 받아온 user
필드를 조건으로 엔티티를 검색하는 것이다. 여기서 사용된 setParameter메서드는 JPQL 쿼리에 사용될 매개 변수를 설정하는 역할을 하게된다. 쿼리문에서 ":user"와 같은 매개 변수 이름을 사용하고, 이 메서드를 사용하여 이 매개 변수에 실제 값인 "user"를 설정하게 되는것이다.
.setParameter(1, user)
이렇게 사용하게되면 Index가 1인 user가 파라미터가 되어 조건으로 엔티티를 검색하게 되게된다.
.setParameter("user", user)
이렇게 사용하면 위에서 설명한것과 동일하게 user필드를 조건으로 엔티티를 검색하게 된다.
getResultList의 경우 결과값을 List의 형태로 받아올건지 single형태로 받아올것인지를 설정해주는 부분이다.
이번 토이프로젝트에서 JPQL은 이렇게 사용했지만 JPQL 쿼리를 더 정확하게 제어하고 쿼리 실행 결과를 타입 안정하게 다룰 때에는 TypedQuery, Query형을 사용하는게 좋다고한다.
반환할 타입을 명확하게 지정할 수 있을때, TypedQuerty객체를 사용한다.
public List<ChatRoom> findChatRoomsByUser(User user) {
TypedQuery<ChatRoom> query = em.createQuery("SELECT c FROM ChatRoom c WHERE c.fiter = :user", ChatRoom.class)
.setParameter("user", user);
List<ChatRoom> chatRooms = query.getResultList();
return chatRooms;
}
위의 쿼리문에서 이렇게 TypedQuery를 이용해 query문을 담고 그 query를 리스트로 객체에 담아 반환하면된다.
반환할 타입을 명확하게 지정할 수 없으면 Query객체를 사용한다.
public List<Object[]> findMemberName(User user) {
Query query = em.createQuery("SELECT m.name, m.age FROM Member m");
List<Object[]> results = query.getResultList();
return results
}
이렇게 반환 타입이 명확하지 않아 Object를 사용할때는 Query 객체를 이용해 검색하는게 안전하다.
Quert를 사용하는 이유를 GPT한테 물어보니 나온 대답이다. 뭐... 정확하진않아 믿거나 말거나 이지만, 동적쿼리와 조인관계를 위해 사용해야하는것같다.
아마 JPQL은 DB를 공부하면서 Query문을 조금 날려봤다 하는 사람들은 어렵지않게 이해할것 같다. 이번 토이프로젝트에서 Repository부분에선 JPQL과 Criteria를 많이 사용했는데, Criteria도 한번 정리해야겠다.