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 을 μ‚¬μš©ν•œλ‹€.

  1. 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 λ₯Ό ν†΅ν•˜μ—¬ κ°’κ³Ό μ—°κ²°ν•˜λŠ” 방식이닀.

  1. 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 ν•œ 것을 λ³Ό 수 μžˆλ‹€.