Sử dụng JPA trong SpringBoot

Giới thiệu nội dung bài viết

Chào các em ,chủ để hôm nay chúng ta sẽ tìm hiểu về các cách để Spring JPA query trong lập trình Spring

Giả sử ta có ta viết một chương trình quản lý nhân sự ở một công ty. Thường ở một công ty sẽ có các phòng ban như : Phòng kế toán, phòng đào tạo, phòng nhân sự. Tại mỗi phòng ban sẽ có các nhân viên thuộc phòng ban đó. Ví dụ ta có entity Phòng ban như sau.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Entity
@Table(name = "phongban")
public class PhongBan implements Serializable {

    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Id
    public int id;

    @Column(name = "ten")
    public String name;

    @Column(name = "mota")
    public String description;
}


1. Sử dung @Query để lấy dữ liệu trong table Department ?

  • Sử dụng JPQL
1
2
3
4
5
6
@Transactional
public interface PhongBanAnnotationRepository extends JpaRepository<PhongBan,Integer> {

    @Query("select phongban from PhongBan phongban)
    PhongBan findAllPhongBan();
}
  • Sử dụng Native Query
1
2
3
4
@Query(
  value = "SELECT * FROM PhongBan phongban WHERE phongban.status = 1",
  nativeQuery = true)
Collection<PhongBan> findAllPhongBan();

Để sử dung câu 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
1
2
@Query("select phongban from PhongBan phongban where phongban.name = ?1")
    PhongBan findByName(String tenphongban);

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 tenphongban. Nếu chúng ta có nhiều tham số ví dụ

1
2
@Query("select phongban from PhongBan phongban where phongban.name = ?1" and phongban.code = ?2)
    PhongBan findByName(String tenphongban,int code);

Lúc đó ?1 sẽ bằng tham số tenphongban 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
1
2
@Query("SELECT nguoidung FROM NguoiDung nguoidung WHERE nguoidung.status = :status and nguoidung.name = :name")
User findUserByStatusAndNameNamedParams(@Param("status") Integer status, @Param("name") String name);

Nó cũng giống na ná như Index query thay vì sử dụng vị trí (index), thì ta sử dung cái 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

1
SELECT nguoidung FROM NguoiDung nguoidung WHERE nguoidung.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

1
2
@Query(value = "SELECT nguoidung FROM NguoiDung nguoidung WHERE nguoidung.name IN :names")
List<User> findUserByNameList(@Param("names") Collection<String> names);


2. Sử dung Query Creation

Spring Data JPA hỗ trở cho chúng ta sẳn các phương thức để truy cập xuống database. Chúng ta chỉ cần kế thừa JPARepository và sau đó có thể sử dụng các phương thức mà JPA cung cấp đề lấy dữ liệu từ database.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public interface PhongBanQueryCreationRepository extends JpaRepository<PhongBan,Integer> {

    List<PhongBan> findByName (String name);
    List<PhongBan> findByNameLike (String name);
    List<PhongBan> findByNameContaining (String name);
    List<PhongBan> findByNameStartingWith(String name);
    List<PhongBan> findByNameEndingWith(String name);
    List<PhongBan> findByNameIgnoreCase(String name);


    List<Department> findByNameAndLocal(String name,String local);
    List<PhongBan> findByNameOrLocal(String name,String local);
    List<PhongBan> findByNameNot(String name);
    List<PhongBan> findByDateAfter(Date date);
    List<PhongBan> findByDateBefore (Date date);
    List<PhongBan> findByDateBetween(Date from,Date to);

}

Trong đó findBy là từ khoá mà JPA cung cấp cho mình sau từ findBy là tên column có 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 column 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


3. Sử dung @NameQuery trong Entiry

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Entity
@Table(name = "NhanVien")
@NamedQuery(name = "NhanVien.fetchByLastNameLength",
        query = "SELECT e FROM NhanVien e WHERE CHAR_LENGTH(e.lastname) =:length "
)
public class NhanVien {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;

    @Column(name = "firstname")
    private String firstName;

    @Column(name = "lastname")
    private String lastname;
 }

Như các em thấy trong Class Entity mình sử dụng @NameQuery để tạo câu lệnh select. Chú ý cho anh chổ @NamedQuery(name = “NhanVien.fetchByLastNameLength”) Để gọi được câu lệnh này thì nơi chỗ JPA Repository ta phải có phương thức (fetchByLastNameLength) giống y chang vậy.

1
2
3
4
5
@Repository
public interface NhanVienRepository extends JpaRepository<Employee,Long>, EmployeeRepositoryCustom {

    List<NhanVien> fetchByLastNameLength(@Param("length") Long length);
}


4. Sử dung Order in Query để sắp xếp dữ liệu theo chiều tăng hoặc giảm dần

1
phongBanRepository.findAll(new Sort(Sort.Direction.ASC, "name"));

Dòng new Sort(Sort.Direction.ASC, “name”) nghĩa là chúng ta muốn sắp xếp dữ liệu ở cột name theo chiều hướng tăng dần. Nếu muốn sắp xếp name theo chiều hướng giảm dần thì ta dùng new Sort(Sort.Direction.DESC, “name”)


5. Sử dụng annotation @Modifying để cập nhật dữ liệu

1
2
3
4
@Modifying
@Query("update NhanVien nhanvien set nhanvien.status = :status where nhanvien.name = :name")
int updateUser(@Param("status") Integer status,
  @Param("name") String name);

Kết quả trả về là bao nhiêu dòng trong database được cập nhật. Chúng ta cũng có thể sử dụng Native Query để cập nhật như sau

1
2
3
4
@Modifying
@Query(value = "update NhanVien nhanvien set nhanvien.status  where nhanvien.name = ?",
  nativeQuery = true)
int updateUserNative(Integer status, String name);


6. Sử dụng annotation @Modifying để insert 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 chúng ta đang dùng không hổ trợ Insert

1
2
3
4
5
6
7
@Modifying
@Query(
  value =
    "insert into NhanVien (name, age, email, status) values (:name, :age, :email, :status)",
  nativeQuery = true)
void insertNhanVien(@Param("name") String name, @Param("age") Integer age,
  @Param("status") Integer status, @Param("email") String email);

7. 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ụ như trong database có 100 dòng. Ta chỉ muốn lấy từ dùng 1 cho tới dòng 10. Để làm được như vậy chúng 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.

1
2
Pageable first10PageWithTwoElements = PageRequest.of(0, 10);
Page<Product> allProducts = productRepository.findAll(first10PageWithTwoElements);
1
2
3
4
public interface ProductRepository extends PagingAndSortingRepository<Product, Integer> {

    List<Product> findAllByPrice(double price, Pageable pageable);
}

Mọi người hãy subcribe kênh youtube dưới đây nhé. Videos về các kỹ năng mềm và lập trình sẽ được cập nhật hằng tuần


Comments