30/08/2018, 23:43

Lập trình Spring với ứng dụng MyContact

MyContact là một ứng dụng mà mình thường viết mỗi khi học một ngôn ngữ hay công nghệ mới. MyContact chỉ là một ứng dụng CRUD đơn giản, cho phép người dùng quản lý danh bạ cá nhân. Theo mình viết ứng dụng thực tế là một trong những cách học hiệu qủa nhất. Thông qua tutorial này, mình ...

MyContact là một ứng dụng mà mình thường viết mỗi khi học một ngôn ngữ hay công nghệ mới. MyContact chỉ là một ứng dụng CRUD đơn giản, cho phép người dùng quản lý danh bạ cá nhân. Theo mình viết ứng dụng thực tế là một trong những cách học hiệu qủa nhất. Thông qua tutorial này, mình hi vọng sẽ giúp các bạn hiểu rõ hơn về Spring cũng như cách áp dụng trong thực tế.

Spring là một đại gia đình với rất nhiều dự án bên trong. Trong tutorial này, mình sẽ chỉ sử dụng các dự án cơ bản sau:

  • Spring Boot để khởi tạo và chạy dự án
  • Spring MVC để xây dựng web app
  • Spring Data để thao tác với cơ sở dữ liệu, cụ thể mình sẽ dùng Spring Data JPA – một thành viên trong gia đình Spring Data

Các công nghệ khác mình sẽ sử dụng:

  • Hệ quản trị CSDL: MySQL
  • ORM framework: Hibernate (cái này đã được tích hợp sẵn trong Spring Data)
  • Template engine: Thymeleaf 2.1 (do phiên bản Spring Boot hiện tại mình đang dùng là 1.4.3 chưa hỗ trợ Thymeleaf 3.0)

Các công cụ bao gồm:

  • Ubuntu 16.04
  • JDK 1.8
  • Eclipse Neon đã cài đặt Spring Tool Suite

Source code của dự án: https://github.com/ntaback26/spring-mycontact

Tổng quan về ứng dụng MyContact

Các chức năng

Ứng dụng bao gồm các chức năng:

  • Hiển thị danh sách liên hệ
  • Thêm liên hệ mới
  • Sửa liên hệ
  • Xóa liên hệ
  • Tìm kiếm liên hệ

Các giao diện

Trang danh sách liên hệ:

screen-shot-2017-01-13-at-2-06-33-pm

Trang thêm/sửa liên hệ:

screen-shot-2017-01-13-at-2-06-54-pm

Source code giao diện: https://github.com/ntaback26/mycontact-html

Cơ sở dữ liệu

Cơ sở dữ liệu chỉ có duy nhất 1 bảng Contact chứa tên, email và số điện thoại của liên hệ:

Xây dựng kiến trúc dự án

Ứng dụng MyContact được xây dựng theo mô hình các lớp (layered). Mỗi một lớp sẽ bao gồm các thành phần có cùng chức năng. Với mô hình này, chúng ta có thể đảm bảo nguyên tắc Đơn trách nhiệm (Single Responsibility), tránh chồng chéo giữa các thành phần, đồng thời inject các dependency cũng dễ dàng hơn. Chúng ta hoàn toàn có thể áp dụng mô hình này với Symfony Framework của PHP hay thậm chí cả AngularJS …

screen-shot-2017-01-13-at-2-07-40-pm

Trong đó:

  • Domain là các POJO, ánh xạ từ các bảng CSDL
  • Repository là các interface trực tiếp truy cập và thao tác với CSDL
  • Service là các lớp có nhiệm vụ xử lý business logic, không trực tiếp truy cập vào CSDL mà sẽ lấy dữ liệu từ Repository, rồi chuyển cho Controller
  • Controller là các lớp chỉ quan tâm đến request của người dùng: đọc input, xử lý input, lấy dữ liệu từ Service đổ ra View. Mỗi một Controller sẽ có nhiều phương thức tương ứng với các use case riêng
  • View là các file html – giao diện người dùng

Chắc các bạn sẽ thắc mắc tại sao mình không để các xử lý business logic trong Controller? Ta thử hình dung, bây giờ ứng dụng MyContact của ta phải cung cấp RESTful Web Service cho một app Android => ta phải viết thêm một RestController. Nếu như không tách riêng thành phần Service thì trong RestController ta bắt buộc phải viết lại các thao tác của Controller đã có. Điều này đã phá vỡ nguyên tắc DRY (Don’t Repeat Yourself).

Dưới đây mình sẽ giải thích rõ hơn workflow của ứng dụng thông qua use case Người dùng truy cập vào trang Danh sách liên hệ:

  • Spring sẽ quét tất cả các Controller, lựa chọn phương thức có URI Pattern phù hợp với URI trên trình duyệt của người dùng
  • Phương thức này sẽ gọi Service để lấy danh sách liên hệ từ CSDL
  • Service không trực tiếp truy cập vào CSDL mà sẽ nhờ Repository lấy tất cả liên hệ trong CSDL.
  • Repository trả về cho Service một danh sách liên hệ tìm thấy, Service lại chuyển danh sách đó cho Controller, rồi Controller sẽ gắn danh sách đó vào một đối tượng Model để đổ ra View

Đến đây, chắc các bạn cũng hiểu sơ qua về kiến trúc của ứng dụng. OK, giờ thì bắt tay vào code thôi!

Áp dụng Spring Framework vào dự án

Khởi tạo dự án

Với công cụ Spring Tool Suite, chúng ta có thể nhanh chóng tạo 1 dự án Spring bằng Spring Boot như sau:

Đầu tiên, ta chọn File -> New -> Other:

screen-shot-2017-01-13-at-2-08-09-pm

Gõ từ khóa spring, chọn Spring Starter Project rồi chọn Next:

screen-shot-2017-01-13-at-2-08-29-pm

Sau đó nhập các thông tin cơ bản như Name, Group, Artifact, Package. Các bạn chú ý Name không được có dấu cách nhé. Ở đây mình sẽ chọn Type là Maven và Java Version là 8:

screen-shot-2017-01-13-at-2-08-49-pm

Sau đó, chọn Next. Spring Boot sẽ yêu cầu chọn các dependency cho dự án. Ở đây, mình sẽ chọn các dependency sau:

  • Web ở trong nhóm Web
  • Security ở trong nhóm Core
  • JPA và MySQL trong nhóm SQL
  • Thymeleaf trong nhóm Template Engines

Sau đó chọn Next:

screen-shot-2017-01-13-at-2-09-11-pm

Chọn Finish:

screen-shot-2017-01-13-at-2-09-30-pm

Qúa trình khởi tạo dự án bắt đầu. Spring Boot sẽ tự động tải các dependency mà ta đã chọn ở trên và tiến hành cấu hình:

screen-shot-2017-01-13-at-2-09-51-pm

Đây là cây thư mục của dự án sau khi khởi tạo xong:

screen-shot-2017-01-13-at-2-10-08-pm

File pom.xml:

Ta thấy cấu hình chung của dự án sẽ gói gọn trong file SpringMyContactApplication.java

Đơn giản hơn rất nhiều so với cách cấu hình thông thường. Cho ta cảm tưởng như đang viết hàm của một ứng dụng console vậy

0