Advanced Search Using Criteria API
Advanced Search Using Criteria API
Here, we’ll use Spring Data JPA’s Criteria API to conduct an advanced search on the student data.
An example of using Criteria API can be found below.
Step 1: Create Spring Boot Project
Open Spring Initializr https://start.spring.io/ website to create a spring boot project.
Step 2: Add Dependencies
Add the following dependencies,
- Spring Web
- Spring Data JPA
- PostgreSQL Driver
- Lombok
Also, Read An Overview of REST and RESTful APIs
Step 3: Create a Student Entity
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
private int age;
private String email;
}
Step 4: Create DTO For Parameters Involved In Advanced Search
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class StudentAdvancedSearchDTO {
private String firstName;
private String lastName;
private Integer age;
private String email;
}
Step 5: Create DAO To Fetch Student Data From The Database
@Repository
public class StudentDAO {
@Autowired
private EntityManager entityManager;
public List<Student> getAllStudents(StudentAdvanceSearchDTO studentAdvanceSearchDTO) {
// create CriteriaBuilder using EntityManager
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
// create CriteriaQuery using CriteriaBuilder
CriteriaQuery<Student> criteriaQuery = criteriaBuilder.createQuery(Student.class);
// create Root
Root<Student> root = criteriaQuery.from(Student.class);
// create Predicate for each of the parameter in StudentAdvanceSearchDTO
List<Predicate> predicates = new ArrayList<>();
if (studentAdvanceSearchDTO.getFirstName() != null) {
predicates.add(criteriaBuilder.like(criteriaBuilder.lower(root.get(“firstName”)),
“%” + studentAdvanceSearchDTO.getFirstName().toLowerCase() + “%”));
}
if (studentAdvanceSearchDTO.getLastName() != null) {
predicates.add(criteriaBuilder.like(criteriaBuilder.lower(root.get(“lastName”)),
“%” + studentAdvanceSearchDTO.getLastName().toLowerCase() + “%”));
}
if (studentAdvanceSearchDTO.getAge() != null) {
predicates.add(criteriaBuilder.equal(root.get(“age”),
studentAdvanceSearchDTO.getAge()));
}
if (studentAdvanceSearchDTO.getEmail() != null) {
predicates.add(criteriaBuilder.like(criteriaBuilder.lower(root.get(“email”)),
“%” + studentAdvanceSearchDTO.getEmail().toLowerCase() + “%”));
}
// add OR logical operator for each of the predicate
if (!predicates.isEmpty()) {
Predicate orPredicate = criteriaBuilder.or(predicates.toArray(new Predicate[0]));
// using WHERE clause
criteriaQuery.where(orPredicate);
}
// create a TypedQuery and return the result list
TypedQuery<Student> typedQuery = entityManager.createQuery(criteriaQuery);
return typedQuery.getResultList();
}
}
Step 6: Create Student Service Class
@Service
public class StudentService {
@Autowired
private StudentDAO studentDAO;
public List<Student> getAllStudents(StudentAdvanceSearchDTO studentAdvanceSearchDTO) {
return studentDAO.getAllStudents(studentAdvanceSearchDTO);
}
}
Also, Read The Pros and Cons of Quarkus vs Spring Boot
Step 7: Configure Database Settings In application.properties File
Here we are using PostgreSQL database.
spring.datasource.url=jdbc:postgresql://localhost:5432/criteria_api_demo
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.hibernate.ddl-auto=update
Step 8: Create a REST End Point To Fetch Data of All Students
@RestController
public class StudentController {
@Autowired
private StudentService studentService;
@GetMapping(“/students”)
public ResponseEntity<List<Student>> getStudents(@RequestBody StudentAdvanceSearchDTO studentAdvanceSearchDTO) {
List<Student> students = studentService.getAllStudents(studentAdvanceSearchDTO);
return new ResponseEntity<>(students, HttpStatus.OK);
}
}
Step 9: Use Postman To Hit The REST End Point
Conclusion
With just a few lines of code and the criteria API offered by the Spring Data JPA, we can efficiently conduct complex searches on data.