当前位置: 首页 > news >正文

MVC、三层架构

1、MVC

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范。
用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
最简单的、最经典就是JSP(view) +Servlet(controller) + JavaBean(model)
视图和逻辑隔离开来
单一职责

控制器是核心
M(Model) 模型 JavaBean
V(View) 视图 Html、JSP、Thymeleaf、Volicity、Freemaker
C(Control) 控制器 Servlet,Controller
1.当控制器收到来自用户的请求
2.控制器调用业务层完成JavaBean数据封装
3.完成业务后通过控制器跳转JSP页面的方式给用户反馈信息
4.JSP个用户做出响应。

什么是JavaBean
JavaBean:一种规范,表达实体和信息的规范,便于封装重用
1.所有属性为private
2.提供默认无参构造方法
3.提供getter和setter
undefined.实现serializable接口

2、三层架构

在这里插入图片描述
在这里插入图片描述
1.Controller:负责控制,拿到View传递过来的数据,封装之后交给Service处理,Service处理完了之后,Controller拿到结果之后,将结果交给界面。
2.Service:业务逻辑(分页,为了完成分页就要调用两次DAO层)
3.Dao:纯粹的JDBC的增删改查操作
上一层可以调用下一层所有代码,并不是StudentServlet只能调用IStudentService代码,也可以调用ITeacherService代码

@WebServlet("/student")
public class StudentServlet extends HttpServlet {private IStudentService studentService = new StudentServiceImpl();private ITeacherService teacherService = new TeacherServiceImpl();}@Service
public class StudentServiceImpl implements IStudentService {private IStudentDao studentDao = new StudentDaoImpl();private ITeacherDao teacherDao = new TeacherDaoImpl();}public class StudentDaoImpl implements IStudentDao {}

先改为两层:
即控制层(controller或servlet)直接调用Dao层
该案例中逻辑层作用不明显,因为也是直接调用Dao
但是当存在复杂逻辑时(如分页),逻辑层必不可少

package com.easy.web.servlet;import com.easy.web.dao.IStudentDao;
import com.easy.web.dao.impl.StudentDaoImpl;
import com.easy.web.pojo.Student;
import com.easy.web.util.JDBCUtil;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;//将list数据放入req中
//浏览器请求服务器,服务器查询数据库返回数据//取名字用于访问
@WebServlet("/student")
//继承什么就是什么
public class StudentServlet extends HttpServlet {private IStudentDao studentDao = new StudentDaoImpl();//访问servlet的时候默认访问service方法//需要重写父类中的service方法@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("UTF-8");System.out.println("StudentServlet.service");//像之前那样写的话一个类光增删改查就需要写四个servlet,如果有十个类就至少需要四十个servlet//所以我们用switch(method)在一个servlet中即可包含增删改查//http://localhost:8080/student?method=selectAll//http://localhost:8080/student?method=deleteById&id=//http://localhost:8080/student?method=addString method = req.getParameter("method");if (method == null || method.equals("")) {method = "selectAll";}switch (method) {case "selectAll":selectAll(req,resp);break;case "deleteById":deleteById(req,resp);break;case "add":add(req,resp);break;case "toUpdate":toUpdate(req,resp);break;case "update":update(req,resp);break;}}//完成update后台操作private void update(HttpServletRequest req, HttpServletResponse resp) throws IOException {System.out.println("StudentServlet.update");String id = req.getParameter("id");String name = req.getParameter("name");String age = req.getParameter("age");String gender = req.getParameter("gender");Student student = new Student(Integer.parseInt(id),name, Integer.parseInt(age),gender);studentDao.update(student);resp.sendRedirect("/student");}//toUpdate是为了去后台拿数据,用于数据回显,是update的一个中间过程//实际上即为根据id来查找private void toUpdate(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//通过selectAll代码修改的System.out.println("StudentServlet.toUpdate");//拿出request中的idString id = req.getParameter("id");Student student = studentDao.selectById(Integer.parseInt(id));//(设置属性)req.setAttribute("student",student);//转发到student_update.jsp页面进行数据回显req.getRequestDispatcher("student_update.jsp").forward(req,resp);}private void add(HttpServletRequest req, HttpServletResponse resp) throws IOException {System.out.println("StudentServlet.add");String name = req.getParameter("name");String age = req.getParameter("age");String gender = req.getParameter("gender");//这里为了好看,在Student类中多弄了一个专门的构造方法//实际上也可以直接用无参的构造方法,然后通过set方法设置Student student = new Student(name,Integer.parseInt(age),gender);studentDao.add(student);//更新类的操作,同样也需要重定向resp.sendRedirect("/student");}private void deleteById(HttpServletRequest req, HttpServletResponse resp) throws IOException {//打印方法名,即使结果没有达到预期效果,你也可以知道是否进行了正常的访问System.out.println("StudentServlet.deleteById");//访问delteStudent之后,我们需要拿到id值才能去删除//拿任何参数都是到req中通过getParameter拿,返回值都是String类型String id = req.getParameter("id");//调用deleteById方法studentDao.deleteById(Integer.parseInt(id));//重定向 302请求//通过resp将重定向的地址告诉浏览器,浏览器自动发送请求//修改(添加、删除)完数据后重定向到“student”页面,将修改后的数据展示出来//即修改数据后,又会到StudentServlet,自动查找所有数据,转发到页面进行展示//resp.sendRedirect("/student");resp.sendRedirect("/student?method=selectAll");}private void selectAll(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("StudentServlet.selectAll");List<Student> list = studentDao.selectAll();//将list数据放入req//(设置属性)req.setAttribute("list",list);//转发到student_list.jsp页面进行展示//(把请求分发)req.getRequestDispatcher("student_list.jsp").forward(req,resp);}
}
package com.easy.web.dao.impl;import com.easy.web.dao.IStudentDao;
import com.easy.web.pojo.Student;
import com.easy.web.util.JDBCUtil;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;//impl即为实现类
//实现原本直接实现在servlet层中的逻辑代码,通过调用的方式实现业务逻辑,可实现复用,且可以简化servlet层代码
public class StudentDaoImpl implements IStudentDao {@Overridepublic List<Student> selectAll() {Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;//扩大作用域,下面要将list数据放到req中List<Student> list = new ArrayList<>();try {//利用工具类方法获取连接connection = JDBCUtil.getConnection();String sql = "SELECT id,name,age,gender FROM student";preparedStatement = connection.prepareStatement(sql);resultSet = preparedStatement.executeQuery();//因为在这里声明的list只能在try的大括号里面使用,下面拿不到,所以需要在try上面声明list,扩大作用域//List<Student> list = new ArrayList<>();while (resultSet.next()) {int id = resultSet.getInt("id");String name = resultSet.getString("name");int age = resultSet.getInt("age");String gender = resultSet.getString("gender");Student student = new Student(id, name, age, gender);list.add(student);}for (Student student : list) {System.out.println(student);}}//ClassNotFoundException在JDBCUtil静态代码块中已被捕获,所以不需要在这里再捕获了catch (SQLException e) {throw new RuntimeException(e);} finally {JDBCUtil.close(connection, preparedStatement, resultSet);}return list;}@Overridepublic void deleteById(Integer id) {Connection connection = null;PreparedStatement preparedStatement = null;//不是查询类,没有结果集try {connection = JDBCUtil.getConnection();String sql = "DELETE FROM student WHERE id=?";//一个一个填补括号中的“?”preparedStatement = connection.prepareStatement(sql);//用Integer.parseInt(id)将id转为int类型preparedStatement.setInt(1,id);//打印出来,显示在执行什么语句(非必须)System.out.println(preparedStatement);//返回影响行数int count = preparedStatement.executeUpdate();System.out.println("count: " + count);} catch (SQLException e) {throw new RuntimeException(e);} finally {JDBCUtil.close(connection,preparedStatement,null);}}@Overridepublic void add(Student student) {Connection connection = null;PreparedStatement preparedStatement = null;//不是查询类,没有结果集try {connection = JDBCUtil.getConnection();String sql = "INSERT INTO student(name,age,gender) VALUES(?,?,?)";//一个一个填补括号中的“?”preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1,student.getName());preparedStatement.setInt(2,student.getAge());preparedStatement.setString(3,student.getGender());//打印出来,显示在执行什么语句(非必须)System.out.println(preparedStatement);//返回影响行数int count = preparedStatement.executeUpdate();System.out.println("count: " + count);} catch (SQLException e) {throw new RuntimeException(e);} finally {JDBCUtil.close(connection,preparedStatement,null);}}@Overridepublic Student selectById(Integer id) {Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;//在这里不再是封装成list集合,封装为一个student对象即可Student student = null;try {connection = JDBCUtil.getConnection();String sql = "SELECT id,name,age,gender FROM student WHERE id=?";preparedStatement = connection.prepareStatement(sql);//填补“?”preparedStatement.setInt(1,id);System.out.println(preparedStatement);resultSet = preparedStatement.executeQuery();while (resultSet.next()) {String name = resultSet.getString("name");int age = resultSet.getInt("age");String gender = resultSet.getString("gender");student = new Student(id, name, age, gender);}}         //ClassNotFoundException在JDBCUtil静态代码块中已被捕获,所以不需要在这里再捕获了catch (SQLException e) {throw new RuntimeException(e);} finally {JDBCUtil.close(connection, preparedStatement, resultSet);}return student;}@Overridepublic void update(Student student) {Connection connection = null;PreparedStatement preparedStatement = null;//不是查询类,没有结果集try {connection = JDBCUtil.getConnection();String sql = "UPDATE student SET name=?,age=?,gender=? WHERE id=?";//一个一个填补括号中的“?”preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1,student.getName());preparedStatement.setInt(2,student.getAge());preparedStatement.setString(3,student.getGender());preparedStatement.setInt(4,student.getId());//打印出来,显示在执行什么语句(非必须)System.out.println(preparedStatement);//返回影响行数int count = preparedStatement.executeUpdate();System.out.println("count: " + count);} catch (SQLException e) {throw new RuntimeException(e);} finally {JDBCUtil.close(connection,preparedStatement,null);}}
}
package com.easy.web.dao;import com.easy.web.pojo.Student;import java.util.List;//Dao数据访问层
//分离数据访问逻辑与业务逻辑,降低两者之间的耦合度。
//接口里面列出来的是能提供的所有功能的清单
public interface IStudentDao {//有关Student类的方法(增删改查)List<Student> selectAll();void deleteById(Integer id);void add(Student student);Student selectById(Integer id);void update(Student student);
}

改为三层:

package com.easy.web.service.impl;import com.easy.web.dao.IStudentDao;
import com.easy.web.dao.impl.StudentDaoImpl;
import com.easy.web.pojo.Student;
import com.easy.web.service.IStudentService;import java.util.List;public class StudentServiceImpl implements IStudentService {//在逻辑层调用Dao层private IStudentDao studentDao = new StudentDaoImpl();@Overridepublic List<Student> selectAll() {return studentDao.selectAll();}@Overridepublic void deleteById(Integer id) {studentDao.deleteById(id);}@Overridepublic void add(Student student) {studentDao.add(student);}@Overridepublic Student selectById(Integer id) {return studentDao.selectById(id);}@Overridepublic void update(Student student) {studentDao.update(student);}
}
package com.easy.web.service;import com.easy.web.pojo.Student;import java.util.List;public interface IStudentService {//有关Student类的方法(增删改查)//与Dao层相同List<Student> selectAll();void deleteById(Integer id);void add(Student student);Student selectById(Integer id);void update(Student student);
}

控制层代码只是调用对象发生了改变

public class StudentServlet extends HttpServlet {//private IStudentDao studentDao = new StudentDaoImpl();//改为三层实现//在控制层调用逻辑层而不直接调用Dao层private IStudentService studentService = new StudentServiceImpl();

Dao代码没有改变

ps:
1、在接口定义中,查询类方法有返回值,修改类方法没有
2、关于id等参数的类型转换,需在控制层即servlet或者controller中调用方法传入参数时直接进行转换

http://www.xdnf.cn/news/1418509.html

相关文章:

  • 手写MyBatis第46弹:多插件责任链模式的实现原理与执行顺序奥秘--MyBatis插件架构深度解析
  • 2025 数字化转型期,值得关注的 10 项高价值证书解析
  • T507 音频调试
  • Redis--Lua脚本以及在SpringBoot中的使用
  • 基于STM32设计的宠物寄养屋控制系统(阿里云IOT)_276
  • 【python+requests】告别繁琐XML解析!用xmltodict.parse像处理JSON一样轻松操作XML
  • MySQL下载及安装(Windows 11)
  • 【图论】 Graph.jl 操作汇总
  • Qt Widgets 之 QAbstractButton
  • 每周读书与学习->认识性能测试工具JMeter
  • Kafka Connect + Streams 用到极致从 CDC 到流处理的一套落地方案
  • UCIE Specification详解(十二)
  • Git中批量恢复文件到之前提交状态
  • 收藏!VSCode 开发者工具快捷键大全
  • 在Linux系统中安装Jenkins(保姆级别)
  • Java:Could not resolve all files for configuration
  • Day42 Grad-CAM与Hook函数
  • UniApp + SignalR + Asp.net Core 做一个聊天IM,含emoji 表情包
  • 【Docker】Docker容器和镜像管理常用命令
  • 【2025ICCV】Vision Transformers 最新研究成果
  • 无题250901
  • GaussDB 集群故障cm_ctl: can‘t connect to cm_server
  • .Net程序员就业现状以及学习路线图(二)
  • oracle默认事务隔离级别
  • Windows神器,按键屏蔽
  • 深入理解 HTTP 与 HTTPS:区别以及 HTTPS 加密原理
  • 【 VPX638】基于KU115 FPGA+C6678 DSP的6U VPX双FMC接口通用信号处理平台
  • 配送算法19 Two Fast Heuristics for Online Order Dispatching
  • Objective-C 的坚毅与传承:在Swift时代下的不可替代性优雅草卓伊凡
  • Java面试宝典:Redis高并发高可用(主从复制、哨兵)