Nội dung
- I. Giới thiệu nội dung bài viết
- II. Sử dụng @Query để lấy dữ liệu trong table Department?
- III. Sử dụng Query Creation
- IV. Sử dụng @NameQuery trong Entity
- V. Sử dụng Order in Query để sắp xếp dữ liệu theo chiều tăng hoặc giảm dần
- VI. Sử dụng Annotation @Modifying để cập nhật dữ liệu
- VII. Sử dụng Annotation @Modifying để chèn dữ liệu
- VIII. Sử dụng Pageable để phân trang
I. Giới thiệu nội dung bài viết
Hôm nay, chúng ta sẽ tìm hiểu về các cách để query dữ liệu từ database thông qua Spring Data JPA. Nội dung sẽ xoay quanh các vấn đề:
- Annotation @Query
- Creation Query
- NameQuery
- Các annotation bổ trợ khác
Giả sử ta có entity như sau:
@Entity @Table(name = "department") public class Department implements Serializable { @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) @Id public int id; @Column(name = "name") public String name; @Column(name = "description") public String description; }
II. Sử dụng @Query để lấy dữ liệu trong table Department?
- Sử dụng JPQL
@Transactional public interface DepartmentAnnotationRepository extends JpaRepository<Department,Integer> { @Query("select department from Department department) Department findAllDepartment(); }
- Sử dụng Native Query
@Query( value = "SELECT * FROM Department u WHERE u.status = 1", nativeQuery = true) Collection<Department> findAllDepartment();
Để sử dụng câu lệnh Query thuần giống như ta thực hiện câu Select trong Database thì mình thêm tham số nativeQuery = true
- Tham số Index trong câu Query
@Query("select department from Department department where department.name = ?1") Department findByName(String departmentName);
Chúng ta dùng ?1 tương ứng với tham số đầu tiên trong method findByName. ?1 sẽ được ánh xạ bằng tham số String departmentName. Nếu chúng ta có nhiều tham số ví dụ
@Query("select department from Department department where department.name = ?1" and department.code = ?2) Department findByName(String departmentName,int code);
Lúc đó ?1 sẽ bằng tham số departmentName và ?2 bằng code. Như vậy dùng ? để chỉ ra thứ tự các tham số trong method tương ứng với vị trí trong câu Query
- Tham số Name trong câu Query
@Query("SELECT u FROM User u WHERE u.status = :status and u.name = :name") User findUserByStatusAndNameNamedParams(@Param("status") Integer status, @Param("name") String name);
Nó cũng giống như Index Query thay vì sử dụng vị trí (Index) thì ta sử dung tên. Ở ví dụ trên, ta sử dụng :status, :name để ánh xạ vào đúng tên (@Param(“status”) Integer status, @Param(“name”) String name) trong phương thức. Chú ý là ta sử dụng thêm @Param để ánh xạ tên method và tên trong @Query giống nhau
- Collection Parameter
Trong database chúng ta có toán tử IN và NOT IN như sau:
SELECT u FROM User u WHERE u.name IN :names
Để sử dụng được toán tử IN trong JPQL Query thì ta sử dụng tham số là Collection như sau:
@Query(value = "SELECT u FROM User u WHERE u.name IN :names") List<User> findUserByNameList(@Param("names") Collection<String> names);
III. Sử dụng Query Creation
Spring Data JPA hỗ trợ cho chúng ta sẵn các phương thức để truy cập vào database. Chúng ta chỉ cần kế thừa JPA Repository là có thể sử dụng được các phương thức mà JPA cung cấp đề lấy dữ liệu từ Database.
public interface DepartmentQueryCreationRepository extends JpaRepository<Department,Integer> { List<Department> findByName (String name); List<Department> findByNameLike (String name); List<Department> findByNameContaining (String name); List<Department> findByNameStartingWith(String name); List<Department> findByNameEndingWith(String name); List<Department> findByNameIgnoreCase(String name); /* List<Department> findByNameAndLocal(String name,String local); List<Department> findByNameOrLocal(String name,String local); List<Department> findByNameNot(String name); List<Department> findByDateAfter(Date date); List<Department> findByDateBefore (Date date); List<Department> findByDateBetween(Date from,Date to); */
Trong đó findBy là từ khoá mà JPA cung cấp, sau từ findBy là tên cột trong database. Ví dụ, findByName tìm kiếm các user có tên là tham số name truyền vào. Trong đó, findBy là từ khoá của JPA và Name chính là tên cột trong database. Ngoài findBy thì JPA còn hỗ trợ nhiều phương thức khác nữa có thể xem ở đây.
IV. Sử dụng @NameQuery trong Entity
@Entity @Table(name = "employee", schema="spring_data_jpa_example") @NamedQuery(name = "Employee.fetchByLastNameLength", query = "SELECT e FROM Employee e WHERE CHAR_LENGTH(e.lastname) =:length " ) public class Employee { @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.SEQUENCE) private Long id; @Column(name = "firstname") private String firstName; @Column(name = "lastname") private String lastname; }
Trong Class Entity, mình sử dụng @NameQuery để tạo câu lệnh Select. Để gọi được câu lệnh @NamedQuery(name = “Employee.fetchByLastNameLength”) thì ở JPA Repository, ta phải có phương thức (fetchByLastNameLength) giống y như vậy.
@Repository public interface EmployeeRepository extends JpaRepository<Employee,Long>, EmployeeRepositoryCustom { List<Employee> fetchByLastNameLength(@Param("length") Long length); }
V. Sử dụng Order in Query để sắp xếp dữ liệu theo chiều tăng hoặc giảm dần
departmentRepository.findAll(new Sort(Sort.Direction.ASC, "name"));
Hàm new Sort(Sort.Direction.ASC, “name”) được sử dụng để sắp xếp dữ liệu ở cột name theo chiều tăng dần Alphabet. Ngược lại, khi muốn sắp xếp cột name theo chiều giảm dần thì ta sử dụng từ khoá DESC.
VI. Sử dụng Annotation @Modifying để cập nhật dữ liệu
@Modifying @Query("update User u set u.status = :status where u.name = :name") int updateUserSetStatusForName(@Param("status") Integer status, @Param("name") String name);
Kết quả trả về là số lượng dòng đã được cập nhật trong Database. Chúng ta cũng có thể sử dụng Native Query để cập nhật như sau
@Modifying @Query(value = "update Users u set u.status = ? where u.name = ?", nativeQuery = true) int updateUserSetStatusForNameNative(Integer status, String name);
VII. Sử dụng Annotation @Modifying để chèn dữ liệu
Trong Spring Data JPA, chúng ta dùng hàm Save() có sẵn để Insert dữ liệu xuống Database. Trong trường hợp dùng Native Query thì chúng ta phải kết hợp @Modifiying và câu lệnh Insert chung với nhau vì Spring Data JPA không hỗ trợ chức năng Insert.
@Modifying @Query( value = "insert into Users (name, age, email, status) values (:name, :age, :email, :status)", nativeQuery = true) void insertUser(@Param("name") String name, @Param("age") Integer age, @Param("status") Integer status, @Param("email") String email);
VIII. Sử dụng Pageable để phân trang
Chúng ta sử dụng Pageable để lấy một tập hợp con trong Database. Ví dụ, trong Database có 100 dòng, ta chỉ muốn lấy từ dòng 1 đến dòng 10. Để làm được điều đó, ta sẽ sử dụng đối tượng PageRequestObject để khai báo số lượng dòng mà ta muốn trả về, sau đó truyền đối tượng PageRequestObject vào câu lệnh truy vấn.
Pageable first10PageWithTwoElements = PageRequest.of(0, 10); Page<Product> allProducts = productRepository.findAll(first10PageWithTwoElements);
public interface ProductRepository extends PagingAndSortingRepository<Product, Integer> { List<Product> findAllByPrice(double price, Pageable pageable); }
Author: Lê Vũ Nguyên
>> Xem ngay Devworld – Cẩm nang giúp lập trình viên phát triển bền vững với nghề lập trình
Đăng ký nhận bộ tài liệu học Java trên 2 trang giấy tại đây
Xem thêm: Java Coding Bootcamp là gì? Tổng quan về Java Coding Bootcamp
Bài viết rất hay, bác làm tiếp Specification nữa thì đẹp 😀
Cảm ơn Nam nhiều nhé!
Trong cái @Modifying có 2 cái nữa là clearAutomatically và flushAutomatically.
A có thể giải thích sâu hơn về 2 cái này được không ạ ?
E đọc mấy cái tiếng Anh mà không hiểu lắm @@