ways to retrieve data from the database
In JPA, there are several ways to retrieve data from the database. These methods can be categorized based on the type of queries they use, such as JPQL (Java Persistence Query Language), Criteria API, and native SQL queries. Each method provides a way to query the database and map the results to entity objects.
Table of Contents
1. Â JPQL (Java Persistence Query Language) Queries
JPQL is a platform-independent object-oriented query language defined as part of the JPA specification. It uses entity names instead of table names and properties instead of columns.
- Creating a Query :
- createQuery(String qlString): Used to create a JPQL query.
String jpql = "SELECT s FROM Student s WHERE s.age > :age";
TypedQuery<Student> query = entityManager.createQuery(jpql, Student.class);
query.setParameter("age", 18);
List<Student> students = query.getResultList();
2. Â Criteria API Queries
The Criteria API is a type-safe and dynamic way to create queries in JPA. It is useful for building queries programmatically.
- Creating a Query :
- CriteriaBuilder: Used to construct query expressions.
- CriteriaQuery<T>: Represents a query object.
java
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Student> cq = cb.createQuery(Student.class);
Root<Student> student = cq.from(Student.class);
cq.select(student).where(cb.greaterThan(student.get("age"), 18));
TypedQuery<Student> query = entityManager.createQuery(cq);
List<Student> students = query.getResultList();
3. Â Named Queries
Named queries are pre-defined, statically defined queries with a specific name. They can be defined using annotations or XML.
java
@Entity
@NamedQuery(name = "Student.findByAge", query = "SELECT s FROM Student s WHERE s.age = :age")
public class Student {
// Fields, getters, setters
}
TypedQuery<Student> query = entityManager.createNamedQuery("Student.findByAge", Student.class);
query.setParameter("age", 18);
List<Student> students = query.getResultList();
4. Â Native SQL Queries
Native queries use raw SQL statements to interact with the database. They are useful when you need to leverage database-specific features.
- Creating a Query :
- createNativeQuery(String sqlString): Used to create a native SQL query.
java
String sql = "SELECT * FROM students WHERE age > ?";
Query query = entityManager.createNativeQuery(sql, Student.class);
query.setParameter(1, 18);
List<Student> students = query.getResultList();
Example Application
Here is an example demonstrating how to use these different query methods in a simple JPA application.
java
package com.example.demo.model;
import javax.persistence.*;
@Entity
@NamedQuery(name = "Student.findByAge", query = "SELECT s FROM Student s WHERE s.age = :age")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private int age;
// Constructors, getters, and setters
public Student() {}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
java
package com.example.demo.service;
import com.example.demo.model.Student;
import javax.persistence.*;
import javax.transaction.Transactional;
import java.util.List;
public class StudentService {
@PersistenceContext
private EntityManager entityManager;
public List<Student> findStudentsUsingJPQL(int age) {
String jpql = "SELECT s FROM Student s WHERE s.age > :age";
TypedQuery<Student> query = entityManager.createQuery(jpql, Student.class);
query.setParameter("age", age);
return query.getResultList();
}
public List<Student> findStudentsUsingCriteriaAPI(int age) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Student> cq = cb.createQuery(Student.class);
Root<Student> student = cq.from(Student.class);
cq.select(student).where(cb.greaterThan(student.get("age"), age));
TypedQuery<Student> query = entityManager.createQuery(cq);
return query.getResultList();
}
public List<Student> findStudentsUsingNamedQuery(int age) {
TypedQuery<Student> query = entityManager.createNamedQuery("Student.findByAge", Student.class);
query.setParameter("age", age);
return query.getResultList();
}
public List<Student> findStudentsUsingNativeQuery(int age) {
String sql = "SELECT * FROM students WHERE age > ?";
Query query = entityManager.createNativeQuery(sql, Student.class);
query.setParameter(1, age);
return query.getResultList();
}
}
java
package com.example.demo.controller;
import com.example.demo.model.Student;
import com.example.demo.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/students")
public class StudentController {
@Autowired
private StudentService studentService;
@GetMapping("/jpql")
public List<Student> findStudentsUsingJPQL(@RequestParam int age) {
return studentService.findStudentsUsingJPQL(age);
}
@GetMapping("/criteria")
public List<Student> findStudentsUsingCriteriaAPI(@RequestParam int age) {
return studentService.findStudentsUsingCriteriaAPI(age);
}
@GetMapping("/named")
public List<Student> findStudentsUsingNamedQuery(@RequestParam int age) {
return studentService.findStudentsUsingNamedQuery(age);
}
@GetMapping("/native")
public List<Student> findStudentsUsingNativeQuery(@RequestParam int age) {
return studentService.findStudentsUsingNativeQuery(age);
}
}
Summary
JPA provides various query methods to retrieve data from the database:
- JPQL Queries : Platform-independent, object-oriented queries.
- Criteria API Queries : Type-safe, programmatic way to build queries.
- Named Queries : Predefined, statically defined queries.
- Native SQL Queries : Raw SQL queries for database-specific features.