Trang chủ » Blog » Truy vấn dữ liệu thông qua Spring Data JPA

Truy vấn dữ liệu thông qua Spring Data JPA

bởi CodeGym | 26/12/2023 15:37 | Blog

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

Download - Giáo trình thuật toán

5 + 10 =

Tags:

3 Lời bình

  1. Nam

    Bài viết rất hay, bác làm tiếp Specification nữa thì đẹp 😀

    Hồi đáp
    • CodeGym

      Cảm ơn Nam nhiều nhé!

      Hồi đáp
  2. Toàn

    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 @@

    Hồi đáp

Gửi Lời bình

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

BÀI VIẾT LIÊN QUAN

BẠN MUỐN HỌC LẬP TRÌNH?

GỌI NGAY

098 953 44 58

Đăng ký tư vấn lộ trình học lập trình

Đăng ký tư vấn, định hướng lộ trình học và giải đáp các thắc mắc về ngành nghề – Miễn phí – Online.

8 + 13 =

TƯ VẤN VỀ LỘ TRÌNH HỌC NGHỀ LẬP TRÌNH TẠI CODEGYM
TƯ VẤN VỀ LỘ TRÌNH HỌC NGHỀ LẬP TRÌNH TẠI CODEGYM