Java web MVC – Tạo mô hình MVC

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"%>