Advanced Search Using Criteria API

Posted By : Vikas Bagri | 08-Jan-2024

Java java microservices Java Virtual Machine

Loading...

Advanced Search Using Criteria API

Here we will be performing advanced search on student's data using Criteria API provided by Spring Data JPA.

Below is an example to illustrate how to use Criteria API.

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 following dependencies,

  • Spring Web
  • Spring Data JPA
  • PostgreSQL Driver
  • Lombok

Also, Read An Overview of REST and RESTful APIs


Step 3: Create 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

Criteria API provided by the Spring Data JPA allows us to perform advanced search on data in a very efficient way while using only a very few lines of code.