Hướng dẫn annotation @Query / NativeQuery trong Spring data
NỘI DUNG BÀI VIẾT
Spring Data annotation @Query
Với annotation @Query
ta có thể khai báo câu query cho các method trong repository.
Việc khai báo câu query với @Query giúp ta tối ưu câu sql, và xử lý trong những trường hợp mà các method do Spring Data không thể đáp ứng:
- Việc sử dụng các method có sẵn khi extends interface
JPARepository
,CrudRepository
không đáp ứng được yêu cầu. - Việc đặt tên method theo chuẩn Query Creation quá dài hoặc tối nghĩa. (Ví dụ bạn muốn truy vấn theo 5 điều kiện thì tên method của bạn sẽ gồm 5 điều kiện đó => quá dài)
Sử dụng @Query
Để sử dụng annotation @Query, ta sẽ khai báo nó trước các method của interface extends từ JPARepository
, CrudRepository
, và truyền câu hsql vào bên trong
Ví dụ:
@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {
@Query("SELECT e FROM Customer e ORDER BY e.name DESC")
List<Customer> findAllOrderByNameDesc();
}
Code language: PHP (php)
Với trường hợp câu sql có tham số từ bên ngoài ta có 2 cách để truyền vào:
Cách 1: truyền theo thứ tự:
@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {
@Query("SELECT e FROM Customer e WHERE e.name = ?1 AND e.address = ?2")
List<Customer> findByNameAndAddress(String name, String address);
}
Code language: PHP (php)
Với cách này thứ tự các tham số của method phải giống với thứ tự các tham số truyền vào câu query
Cách 2: sử dụng annotation @Param
@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {
@Query("SELECT e FROM Customer e WHERE e.name = :name AND e.address = :address")
List<Customer> findByNameAndAddress(@Param("name") String name, @Param("address") String address);
}
Code language: PHP (php)
Bản thân mình thấy cách này rõ ràng hơn, câu query vừa dễ đọc lại không lo nhầm thứ tự các tham số.
Kết quả trả về của method sử dụng @Query
Kết quả trả về của method sử dụng @Query có thể là:
Một List:
@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {
@Query("SELECT e FROM Customer e WHERE e.name = :name")
List<Customer> findByName(@Param("name") String name);
}
Code language: PHP (php)
Một Stream:
@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {
@Query("SELECT e FROM Customer e WHERE e.name = :name")
Stream<Customer> findByName(@Param("name") String name);
}
Code language: PHP (php)
Ta dùng stream cho những trường hợp kết quả của câu query có quá nhiều bản ghi, thay vì phải tạo rất nhiều đối tượng để lưu các bản ghi đó ta sẽ tạo ra 1 stream, và nó chỉ thực sự tạo ra các đối tượng khi bạn sử dụng đến phần tử bên trong stream.
Một Page:
@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {
@Query("SELECT e FROM Customer e WHERE e.name = :name")
Page<Customer> findByName(@Param("name") String name, Pageable pageable);
}
Code language: PHP (php)
(Việc trả về Page áp dụng cho trường hợp muốn phân trang, mình sẽ nói rõ hơn ở bài sau)
Một đối tượng:
@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {
@Query("SELECT e FROM Customer e WHERE e.name = :name")
Customer findByName(@Param("name") String name);
}
Code language: PHP (php)
Ta chỉ sử dụng khi chắc chắn kết quả của câu query sẽ trả về 1 đối tượng, nếu câu query trả về nhiều hơn 1 đối tượng thì sẽ xảy ra lỗi.
Sử dụng NativeQuery
Để sử dụng native query ta sử dụng thuộc tính nativeQuery = true
bên trong annotation @Query
Ví dụ:
@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {
@Query(value = "SELECT e.* FROM customer e ORDER BY e.name DESC", nativeQuery = true)
List<Customer> findAllOrderByNameDesc();
}
Code language: PHP (php)
Okay, Done!
Nguồn: https://stackjava.com/spring/huong-dan-annotation-query-nativequery-trong-spring-data.html
Leave a Reply