1. MVC là gì?
MVC là một mô hình thiết kế, giúp bạn tổ chức code theo từng phần độc lập với nhau, và các phần tương tác với nhau theo một cách nhất định.
Mô hình MVC gồm 3 lớp: Model, View, Controller. Cụ thể như sau:
- Model: Lớp này chịu trách nhiệm quản lí dữ liệu: giao tiếp với cơ sở dữ liệu, chịu trách nhiệm lưu trữ hoặc truy vấn dữ liệu.
- View: Lớp này chính là giao diện của ứng dụng, chịu trách nhiệm biểu diễn dữ liệu của ứng dụng thành các dạng nhìn thấy được.
- Controller: Lớp này đóng vai trò quản lí và điều phối luồng hoạt động của ứng dụng. Tầng này sẽ nhận request từ client, điều phối các Model và View để có thể cho ra output thích hợp và trả kết quả về cho người dung.
Mô hình hoạt động
Trình duyệt gửi một request lên server, server nhận được request sẽ phân tích và gửi dữ liệu vào controller dựa vào router điều hướng. Trong vài trường hợp thì controller sẽ render luôn ra view (một template được chuyển thành HTML) và gửi trả về cho trình duyệt. Nhưng thông thường, cho các trang web động, controller sẽ tương tác với một model (đại diện cho một phần tử ví dụ như Post, chịu trách nhiệm giao tiếp với cơ sở dữ liệu). Sau khi gọi vào model, controller sẽ render view với dữ liệu lấy được và trả kết quả về cho trình duyệt để hiển thị.
2. Cấu trúc dự án
Chúng ta chia package: model, controller, view
2.1. Model
Với mỗi bảng cơ sở dữ liệu chúng ta xây dựng các phương thức để thêm đọc sửa xoá (CRUD – Create Read Update Delete) cơ sở dữ liệu
package binh.dev.data.dao; import java.util.List; import binh.dev.data.model.Category; public interface CategoryDao { public boolean insert(Category category); public boolean update(Category category); public boolean delete(int id); public Category find(int id); public List<Category> findAll(); public List<Category> hotCategory(); }
BẢNG CATEGORIES
- Create
Thêm mới 1 category
- Read
Lấy toàn bộ categories
- Update
Cập nhật 1 category
- Delete
Xoá 1 category trong categories
Lớp CategoryImpl Implements CategoryDao thực thi
Tạo tập tin binh.dev.data.impl.CategoryImpl.java
package binh.dev.data.impl; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import binh.dev.data.dao.CategoryDao; import binh.dev.data.driver.MySQLDriver; import binh.dev.data.model.Category; public class CategoryImpl implements CategoryDao { Connection con = MySQLDriver.getInstance().getConnection(); @Override public boolean insert(Category category) { // TODO Auto-generated method stub String sql = "INSERT INTO CATEGORIES VALUES(NULL, ?, ?)"; try { PreparedStatement stmt = con.prepareStatement(sql); stmt.setString(1, category.getName()); stmt.setString(2, category.getThumbnail()); stmt.execute(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; } @Override public boolean update(Category category) { // TODO Auto-generated method stub String sql = "UPDATE CATEGORIES SET name = ?, thumbnail = ? WHERE id = ?"; try { PreparedStatement stmt = con.prepareStatement(sql); stmt.setString(1, category.getName()); stmt.setString(2, category.getThumbnail()); stmt.setInt(3, category.getId()); return stmt.execute(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; } @Override public boolean delete(int id) { // TODO Auto-generated method stub String sql = "DELETE FROM CATEGORIES WHERE ID = ?"; try { PreparedStatement stmt = con.prepareStatement(sql); stmt.setInt(1, id); return stmt.execute(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; } @Override public Category find(int id) { // TODO Auto-generated method stub String sql = "SELECT * FROM CATEGORIES WHERE ID = ?"; try { PreparedStatement stmt = con.prepareStatement(sql); stmt.setInt(1, id); ResultSet rs = stmt.executeQuery(); while (rs.next()) { String name = rs.getString("name"); String thumbnail = rs.getString("thumbnail"); return new Category(id, name, thumbnail); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } @Override public List<Category> findAll() { // TODO Auto-generated method stub List<Category> cateList = new ArrayList<>(); String sql = "SELECT * FROM CATEGORIES"; try { PreparedStatement stmt = con.prepareStatement(sql); ResultSet rs = stmt.executeQuery(); while (rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); String thumbnail = rs.getString("thumbnail"); cateList.add(new Category(id, name, thumbnail)); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return cateList; } @Override public List<Category> hotCategory() { List<Category> cateList = new ArrayList<>(); String sql = "SELECT * FROM CATEGORIES LIMIT 4"; try { PreparedStatement stmt = con.prepareStatement(sql); ResultSet rs = stmt.executeQuery(); while (rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); String thumbnail = rs.getString("thumbnail"); cateList.add(new Category(id, name, thumbnail)); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return cateList; } }
BẢNG PRODUCTS
Tương tự với bảng categories ta cũng có 2 lớp
Interface ProductDao khai báo các action (binh.dev.data.dao.ProductDao.java)
Lớp ProductImpl implements interface ProductDao (binh.dev.data.impl.ProductImpl.java)
Github:
BẢNG USERS
Tương tự với bảng categories ta cũng có 2 lớp
Interface UserDao khai báo các action (binh.dev.data.dao.UserDao.java)
Lớp UserImpl implements interface UserDao (binh.dev.data.impl.UserImpl.java)
Github:
BẢNG ORDERS
Tương tự với bảng categories ta cũng có 2 lớp
Interface OrderDao khai báo các action (binh.dev.data.dao.OrderDao.java)
Lớp OrderImpl implements interface OrderDao (binh.dev.data.impl.OrderImpl.java)
Github:
BẢNG ORDER_ITEMS
Tương tự với bảng categories ta cũng có 2 lớp
Interface OrderItemDao khai báo các action (binh.dev.data.dao.OrderItemDao.java)
Lớp OrderItemImpl implements interface OrderItemDao (binh.dev.data.impl.OrderItemImpl.java)
Github:
2.2. Controller
Sử dụng Servlet đóng vai trò là controller
package binh.dev; import java.io.IOException; import java.io.PrintWriter; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.util.List; import binh.dev.data.dao.DatabaseDao; import binh.dev.data.dao.ProductDao; import binh.dev.data.model.Category; import binh.dev.data.model.Product; import binh.dev.util.Constants; /** * * @author ACER NITRO */ public class HomeServlet extends BaseServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { super.doGet(request, response); ProductDao productDao = DatabaseDao.getInstance().getProductDao(); List<Product> productList = productDao.hot(Constants.VIEW_LIMIT); List<Product> hotProductList = productDao.hot(Constants.VIEW_NUMBER); List<Category> hotcategoryList = DatabaseDao.getInstance().getCategoryDao().hotCategory(); request.setAttribute("productList", productList); request.setAttribute("hotProductList", hotProductList); request.setAttribute("hotcategoryList", hotcategoryList); request.getRequestDispatcher("home.jsp").include(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); out.print("Method POST"); } }
2.3. View
Sử dụng jsp đóng vai trò là view
<%-- Document : home Created on : May 5, 2023, 7:19:37?PM Author : binhdev --%> <%@include file="./inc/header.jsp"%> <%@ taglib prefix = "fmt" uri = "http://java.sun.com/jsp/jstl/fmt" %> <div id=app__container""> </div> <%@include file="./inc/footer.jsp"%>