Sử dụng JPA trong Spring MVC

Mình đã hướng dẫn các bạn cách sử dụng JPA trong Spring framework như thế nào trong bài viết trước. Trong bài viết này mình sẽ tiếp tục hướng dẫn các bạn cách sử trong JPA trong Spring MVC các bạn nhé!

Đầu tiên, mình cũng sẽ tạo một Maven project để làm ví dụ:

Sử dụng JPA trong Spring MVC

Bạn nào chưa biết cách tạo thì làm theo hướng dẫn của bài viết này nhé các bạn!

Các dependencies mặc định mình đã thay đổi version như sau:

Để làm việc với JPA, chúng ta cần thêm spring-orm dependency nữa:

Để làm việc với JPA với implementation là Hibernate, mình cần thêm dependency của Hibernate như sau:

MySQL Connector:

Mình sẽ sử dụng Project Lombok để khỏi phải khai báo những phương thức Getter hay Setter, …

Để chạy project này, mình sẽ sử dụng Maven Jetty Pluggin:

Trong ví dụ này, mình sẽ tạo một ứng dụng web nhỏ cho phép người dùng có thể truy vấn thông tin của một sinh viên.

Chúng ta sẽ tổ chức project theo mô hình: từ Controller muốn thao tác qua database phải thông qua các class Service. Các class Service sẽ đóng vai trò trung gian và những thứ liên quan đến database sẽ không được sử dụng trực tiếp trong Controller.

Để làm được điều này, chúng ta cần thực hiện lần lượt từng bước sau:

Đầu tiên, chúng ta cần định nghĩa database lưu thông tin của sinh viên.

Để đơn giản, mình sẽ định nghĩa một table chứa thông tin sinh viên với 2 cột như sau:

Tiếp theo, mình sẽ định nghĩa entity Student thể hiện thông tin của table student.

Trong entity này, mình sẽ sử dụng annotation @Data của Project Lombok để khỏi phải khai báo các phương thức Getter, Setter, toString(), equals() hay hashCode().

Để làm việc với JPA, tương tự như trong Spring framework, chúng ta cũng cần một tập tin persistence.xml cấu hình cho nó.

Các bạn hãy tạo mới tập tin persistence.xml nằm trong thư mục /src/main/resources/META-INF các bạn nhé!

Nội dung của tập tin này như sau:

Bây giờ, chúng ta cũng đi khai báo EntityManagerFactory trong Spring container.

Tương tự như trong Spring framework, mình cũng sử dụng LocalContainerEntityManagerFactory và khai báo nó như sau trong tập tin /src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml:

Chúng ta sẽ sử dụng interface StudentDao và implementation của nó là StudentDaoImpl để thao tác trực tiếp với database.

Interface StudentDao có nội dung như sau:

Class StudentDaoImpl implement interface StudentDao sẽ được khai báo với annotation @Repository (dùng để khai báo với Spring bean này sẽ làm việc với database). Nội dung của class này như sau:

Trong class này mình đã inject đối tượng EntityManager từ Spring container bằng annotation @PersistenceContext. Và chúng ta sẽ sử dụng đối tượng EntityManager này để tìm kiếm sinh viên theo ID.

Để Controller có thể thao tác với database, mình sẽ tạo mới interface StudentService và implementation của nó là StudentServiceImpl cho Controller sử dụng.

Interface StudentService có nội dung như sau:

Và class implementation StudentServiceImpl:

Ở đây, mình đã khai báo class StudentServiceImpl sử dụng annotation @Service và mình cũng đã inject bean StudentDao vào đối tượng StudentServiceImpl để thao tác với database.

Ở đây, mình còn sử dụng một đối tượng Student khác, chỉ sử dụng ở level Service và Controller. Việc tách bạch giữa đối tượng Student cho database và đối tượng Student cho level Controller sẽ giúp chúng ta dễ chỉnh sửa sau này.

Nội dung của class com.huongdanjava.springmvcjpa.web.entity.Student như sau:

Bây giờ thì chúng ta sẽ sử dụng bean StudentService trong Controller để nó có thể thông qua đối tượng này thao tác với database.

Mình sẽ chỉnh sửa class HomeController sử dụng StudentService để tìm thông tin của sinh viên theo ID như sau:

Sau khi có kết quả, mình sẽ đưa nó vào Model với key là “student” để hiển thị trên View như sau:

Vậy là chúng ta đã hoàn thành các bước cần thiết rồi đó các bạn. Giờ thì chạy lên thôi!

Giả sử database mình đang có dữ liệu như sau:

Sử dụng JPA trong Spring MVC

thì khi chạy kết quả sẽ như sau:

Sử dụng JPA trong Spring MVC

 

11 thoughts on “Sử dụng JPA trong Spring MVC

  1. a ơi !! cho e hỏi đoạn StudentServiceImpl inject Interface StudentDAO , thế sao n lại dùng được phương thức trong class StudentDAOImpl ạ ???

  2. anh cho em hỏi:
    ở class ” StudentDaoImpl implement StudentDao” có thuộc tính private ” EntityManager em;” dùng @PersistenceContext nhưng trong spring container em không thấy có khai báo bean nào loại EntityManager được khai báo, là sao ạ. Anh giải thích giúp em với.

  3. mình bị như này là gì vậy ad
    No qualifying bean of type ‘com.huongdanjava.springmvcjpa.service.StudentService’ available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

  4. Chào Khánh. Bạn có thể giải thích hoặc đưa ra 1 trường hợp nhặp nhằn khi không sử dụng lớp DTO (student cho controller) như bạn nói ở trên không nhỉ ?

    1. Hi bạn,

      Việc tách bạch vậy sẽ có ích rất nhiều trong những ứng dụng lớn. Việc thay đổi trong database sẽ không ảnh hưởng nhiều với controller và ngược lại.

      Ví dụ như bây giờ mình cần thêm một cột trong table student trong database để phục vụ cho 1 request khác. Nếu mà controller mình dùng entity của table này, bạn có thể thấy nó sẽ ảnh hưởng đến kết quả trả về của request. Một sự thay đổi nhỏ trong database, sẽ ảnh hưởng đến rất nhiều cho hệ thống, bạn phải sửa tất cả những thứ liên quan.

      Hi vọng là bạn hình dung được.

      1. Chào Khánh.
        Mình xin chân thành cảm ơn câu trả lời của bạn. Bạn đã gỡ khuất mắt bấy lâu nay của mình. Mình xin cảm ơn bạn 1 lần nữa 🙂

Add Comment