JPA Query Language (JPQL)
JPQL(Java Persistence Query Language)은 JPA(Jakarta Persistence API) 에서 사용되는 Object-Oriented query language 로, Database Table 이 아닌 Entity Object 를 대상으로 query 를 작성하는 데 사용된다.
SQL 과 문법이 유사하지만, JPQL 은 Entity object 중심적이며, JPA 가 이를 SQL 로 변환하여 실행한다. 즉, JPQL 은 enitity name 과 entity fields 를 기반으로 두고 있다. 또한 주로 database 에서 object 를 retrieve 할 때 사용된다.
Retrieving all Students
TypedQuery<Student> theQuery = entityManager.createQuery("FROM Student", Student.class);
List<Student> students = theQuery.getResultList();위와 같이 작성하면 datatbase table 에서 모든 Student object 들을 retrieving 할 수 있다. 코드를 보면 알겠지만, JPQL syntax 는 실제 DB 의 table name 이나 column name 이 아니라 Entity Class 의 name 과 fields 를 기반으로 작성한다.
TypedQuery 는 return type 이 명확할 때 사용하며, 명확하지 않을 때에는 Query 를 사용한다. Query 를 사용할 때에는 다음과 같이 사용한다.
Query query = entityManager.createQuery(jpql);
List<Object[]> result = query.getResultList();Retrieving Students: lastName='lastname'
.createQuery("FROM Student WHERE lastName='Slot'", Student.class);이번에는 특정 column 에 대한 값을 지정하여 원하는 object 만 retrieving 해보자.
Retrieving Students: Using OR Predicate
.createQuery("FROM Student WHERE lastName='Slot' OR fistName='Alisson'", Student.class);Retrieving Students: Using LIKE Predicate
.createQuery("FROM Student WHERE email LIKE '%liverpool.com'", Student.class);Parmeter Binding
JQPL 에서는 query 에 사용되는 dynamic value 를 처리하기 위하여, 즉 query 에 값을 dynamic 하게 전달하기 위하여 Parameter Binding 을 사용한다.
- Named Parameter Binding
String jpql = "SELECT s FROM Student s WHERE s.name = :name";
query.setParameter("name", "John");Named Parameter 는 query 에서 parameter name 을 :name 의 syntax 로 define 하고, 이를 setParameter method 를 통하여 값과 연결하는 방식이다.
- Positional Parameter Binding
String jpql = "SELECT s FROM Student s WHERE s.name = :name";
query.setParameter(1, "John");Positional Parameter 는 query 에서 parameter 를 ?number 의 syntax 로 define 하고, 이를 setParameter method 를 통하여 값과 연결하는 방식이다.
Positional Parameter Binding 은 query 가 복잡해질수록 관리가 어려워지고 가독성이 떨어진다. 따라서 일반적으로는 Named Parameter Binding 을 사용하는 것이 Conventional 하다.
JPQL - SELECT clause
위에서 query 를 생성할 때, 어떤 query 는 SELECT clause 를 포함하고 있고, 다른 query 는 명시적으로 적어주었다.
Hibernate 를 사용하는 환경에서는 HQL(Hibernate Query Language) 을 제공하기 때문에 SELECT 를 생략해도 된다. 하지만 strict 한 JPQL 에서는 반드시 SELECT clause 를 사용해야 한다.
그러나 Hibernate 를 사용하는 경우 SELECT 를 생략해도 동작하지만, 명시적으로 사용하는 것이 코드의 가독성과 유지보수성을 높이는 데 도움이 된다.
JPQL - Development
Step 1: Add new method to DAO Interface
public interface StudentDAO {
...
List<Student> findAll();
}Step 2: Define DAO Implementation
public class StudentDAOImpl implements StudentDAO {
private EntityManager entityManager;
...
@Override
public List<Student> findAll() {
TypedQuery<Student> theQuery = entityManager.createQuery("SELECT s FROM Student s", Student.class)
return theQuery.getResultList();
}
}마찬가지로 단순히 SELECT 에 해당하는 query 이기 때문에 @Transactional annotation 을 사용할 필요는 없다.
Step 3: Update Main Application
@SpringBootApplication
public class CruddemoApplication {
public static void main(String[] args) {
SpringApplication.run(CruddemoApplication.class, args);
}
@Bean
public CommandLineRunner commandLineRunner(StudentDAO studentDAO) {
return runner -> {
queryForStudents(studentDAO);
}
}
private void queryForStudents(StudentDAO studentDAO) {
// get list of students
List<Student> theStudents = studentDAO.findAll();
// display list of students
for (Student tempStudent : theStudents) {
System.out.println(tempStudent);
}
}
}JPQL - Test

위와 같이 Student table 에 존재하는 모든 object 를 retrieving 한 것을 볼 수 있다.