Học viên: Vũ Bá Phúc
Lớp: Java Fullstack 15
Email: phucnhan20022022@gmail.com
Số điện thoại: 0968616076
Nguồn tham khảo : https://www.baeldung.com

1. Tổng Quan

Trong hướng dẫn này, chúng tôi sẽ trình bày cách xử lý các tham số null trong Spring Data JPA.

Trong một số trường hợp, khi tìm kiếm đối tượng hay bản ghi theo tham số, chúng tôi muốn tìm các đối tượng có giá trị là null. Chúng tôi muốn bỏ qua giá trị null và và bỏ qua tham số đó trong câu truy vấn Query của mình.

Dưới đây chúng tôi sẽ chỉ ra cách thực hiện điều này.

2. Ví dụ

Giả sử chúng ta có một Entity là Customer:

@Entity
public class Customer {

    @Id
    @GeneratedValue
    private long id;
    private String name;
    private String email;

    public Customer(String name, String email) {
        this.name = name;
        this.email = email;
    }

    // getters/setters

}

Ngoài ra, chúng ta có một JPA repository:

public interface CustomerRepository extends JpaRepository<Customer, Long> { 

   // method1
   // method2
}

Chúng ta muốn tìm kiếm khách hàng theo nameemail.
Với mục đích này, chúng ta sẽ viết 2 Method xử lý các tham số null khác nhau.

3. Cách sử lý với các tham số Null

Đầu tiên, chúng ta sẽ tạo một Method diễn giải các giá trị null của các tham số là IS NULL. Sau đó chúng ta sẽ tạo một Method nỏ qua các tham số null và loại bỏ nó khỏi mệnh đề WHERE.

3.1. IS NULL Query

Method đầu tiên rất đơn giản để tạo nó vì các tham số null của các tham số null trong các Query Method được hiểu là IS NULL theo mặc định.

Hãy tạo Method:

List<Customer> findByNameAndEmail(String name, String email);

Bây giờ nếu chúng ta chuyển emailnull. JPQL được tạo sẽ bao gồm điều kiện IS NULL:

customer0_.email is null

Để chúng minh điều này, hãy tạo một bài để kiểm tra.

Đầu tiên, chúng ta sẽ thêm một số khách hàng vào kho lưu trữ:

@Before
public void before() {
    entityManager.persist(new Customer("A", "A@example.com"));
    entityManager.persist(new Customer("D", null));
    entityManager.persist(new Customer("D", "D@example.com"));
}

Bây giờ, hãy chuyển “D” thành giá trị tham số của namenull là giá trị tham số của email cho Query Method của chúng ta.

Chúng ta có thể thấy rằng chính xác một khách hàng sẽ được tìm thấy:

List<Customer> customers = repository.findByNameAndEmail("D", null);

assertEquals(1, customers.size());

Customer actual = customers.get(0);

assertEquals(null, actual.getEmail());
assertEquals("D", actual.getName());

3.2. Sử dụng các Method khác để tránh các tham số null

Đôi khi chúng ta muốn bỏ qua một số tham số và không bao gồm các trường tương ứng của chúng trong mệnh đề WHERE.

Chúng ta có thể thêm nhiều Query Method hơn trong kho lưu trữ của mình.

Ví dụ, để bỏ qua email, chúng ta có thể thêm một Method chỉ chấp nhập name:

 List<Customer> findByName(String name);

Nhưng cách này để bỏ qua 1 tham số trong đó thì có tỷ lệ thấp khi số lượng tăng lên vì chúng ta sẽ phải thêm nhiều Method để đạt được tất cả các yêu cầu.

3.3. Bỏ qua các tham số null bằng @Query Annotation

Chúng ta có thể tránh tạo các phương thức bổ sung bằng cách sử dụng @Query Annotation và thêm một sự phức tạp nhỏ và cấu lệnh JPQL:

@Query("SELECT c FROM Customer c WHERE (:name is null or c.name = :name) and (:email is null"
  + " or c.email = :email)")
List<Customer> findCustomerByNameAndEmail(@Param("name") String name, @Param("email") String email);

Lưu ý rằng các tham số emailnull, thì mệnh đề luôn đúng và do đó không ảnh hưởng đến toàn bộ mệnh đề WHERE:

:email is null or s.email = :email

Hãy chắc chắn rằng điều này hoạt động:

List<Customer> customers = repository.findCustomerByNameAndEmail("D", null);

assertEquals(2, customers.size());

Chúng ta tìm thấy hai khách hàng có tên là “D” và bỏ qua email của họ.

Mệnh đề JPQL WHERE được tạo trông giống như sau:

where (? is null or customer0_.name=?) and (? is null or customer0_.email=?)

Với phương pháp này, chúng ta đặt niềm tin vào máy chủ cơ sở dữ liệu để nhận ra mệnh đề liên quan đến tham số truy vấn của chúng ta là null và tối ưu hóa kế hoạch thực hiện truy vấn để nó không có chi phí hoạt động đáng kể. Đối với một số truy vấn hoặc máy chủ cơ sở dữ liệu, đặc biệt là liên quan đến bảng lớn, có thể có chi phí hoạt động.

4. Kết Luận

Trong bài viết này, chúng tôi đã trình bày cách Spring Data JPA diễn giải các tham số null trong các phương thức truy vấn và thay đổi cách truy vấn mặc định.

Có lẽ trong tương lai, chúng tôi sẽ có thể chỉ định cách diễn giải các tham số null bằng cách sử dụng chú thích @NullMeans. Lưu ý rằng đó là một tính năng được đề xuất vào thời điểm này và vẫn đang được xem xét.

Tóm lại, có hai cách chính để diễn giải các tham số null và cả hai cách này đều được cung cấp bởi chú thích @NullMeans được đề xuất :

  • IS (là null) – tùy chọn mặc định được trình bày trong Phần 3.1.
  • BỎ QUA (loại trừ tham số null khỏi mệnh đề WHERE ) – đạt được bằng các phương thức truy vấn bổ sung (Phần 3.2.) hoặc bằng cách sử dụng giải pháp thay thế (Phần 3.3.)