JavaWeb06-MVC和三层架构
目录
一、MVC模式
1.概述
2.好处
二、三层架构
1.概述
三、MVC与三层架构
四、练习
一、MVC模式
1.概述
MVC是一种分层开发的模式,其中
M:Model,业务模型,处理业务 V: View,视图,界面展示 C:Controller,控制器,处理请求,调用型和视图

2.好处
-
职责单一,互不影响
-
有利于分工协作
-
有利于组件重用
二、三层架构
1.概述

View视图不只是JSP!
数据访问层(持久层):对数据库的CRUD基本操作
一般命名为反转公司网址/controller
业务逻辑层(业务层):对业务逻辑进行封装,组合数据访问层层中基本功能,形成复杂的业务逻辑功能。
一般命名为反转公司网址/service
表现层:接收请求,封装数据,调用业务逻辑层,响应数据
一般命名为反转公司网址/dao或者mapper
三、MVC与三层架构

四、练习
给上次的数据添加一个状态字段,0禁用,1启用,2预售,设个默认值1即可
使用三层架构思想开发
参考下图:

java目录结构

代码,只写主要的了
service包下
public class ProductService {final SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();public List<Product> selectAll(){final SqlSession sqlSession = sqlSessionFactory.openSession();final ProductMapper mapper = sqlSession.getMapper(ProductMapper.class);final List<Product> products = mapper.selectAll();sqlSession.close();return products;};
}
web包下
@WebServlet("/selectAll")
public class selectAll extends HttpServlet {private final ProductService productService = new ProductService();@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
final List<Product> products = productService.selectAll();request.setAttribute("product",products);request.getRequestDispatcher("/jsp/product.jsp").forward(request,response);}
@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
}
之后回到视图层

jsp:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--Created by IntelliJ IDEA.User: LEGIONDate: 2024/3/13Time: 13:36To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<%--<% final Object product = request.getAttribute("product");%>--%>
<html>
<head><title>Title</title>
</head>
<body><h1>product列表</h1><table border="1px solid black"><tr><th>商品序号</th><th>商品id</th><th>商品名</th><th>商品图片</th><th>商品价格</th><th>商品评论数</th><th>商品分类</th><th>商品状态</th><th>商品发布时间</th><th>商品更新时间</th></tr><c:forEach items="${product}" var="product" varStatus="status"><tr><%-- index从0开始,count从1开始--%><td>${status.count}</td><%-- ${user.id} => Id => getId()--%><td>${product.id}</td><td>${product.title}</td><td><img src="${product.imgUrl}" alt="" width="75px" height="75px"></td><td>${product.price}</td><td>${product.comment}</td><td>${product.category}</td><td>${product.status}</td><td>${product.gmtCreate}</td><td>${product.gmtModified}</td></tr></c:forEach>
</table>
</body>
</html>
预览图:

添加:
html
<form action="/product_demo_war/add" method="post"><input type="text" name="title" placeholder="商品名称"><br><input type="text" name="price" placeholder="商品价格"><br>
<!-- 图片上传在这里就先不写了--><input type="number" name="category" placeholder="商品类型(数字就好)"><br><input type="radio" name="status">启用<input type="radio" name="status">禁用<br><input type="submit" value="添加"></form>
service:
/*** 添加商品* @param product 商品对象*/
public void add(Product product){final SqlSession sqlSession = sqlSessionFactory.openSession();final ProductMapper mapper = sqlSession.getMapper(ProductMapper.class);mapper.add(product);sqlSession.commit();sqlSession.close();
}
web:
@WebServlet("/add")
public class Add extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {ProductService productService = new ProductService();final String title = request.getParameter("title");final String price = request.getParameter("price");final Integer status = Integer.parseInt(request.getParameter("status"));final Integer category = Integer.parseInt(request.getParameter("category"));Product product = new Product(title,price,category,status);productService.add(product);request.getRequestDispatcher("/selectAll").forward(request,response);}
@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
}
预览:

修改:
有两步:
-
显示原先的数据:回显
-
修改现有的数据:修改
第一部分回显:根据id显示值
service:
public Product selectById(Long id){final SqlSession sqlSession = sqlSessionFactory.openSession();final ProductMapper mapper = sqlSession.getMapper(ProductMapper.class);final Product product = mapper.selectById(id);sqlSession.close();return product;
}
web:
@WebServlet("/selectById")
public class SelectById extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {final String id = request.getParameter("id");ProductService productService = new ProductService();final Product product = productService.selectById(Long.parseLong(id));request.setAttribute("product",product);System.out.println(id);request.getRequestDispatcher("/jsp/productUpdate.jsp").forward(request,response);}
@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
}
显示层:productUpdate.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head><title>修改</title><style>.text {width: 100%;}</style>
</head>
<body>
<form action="/product_demo_war/updateById" method="post"><input type="hidden" name="id" value="${product.id}"><input class="text" type="text" name="title" placeholder="商品名称" value="${product.title}"><br><input class="text" type="text" name="price" placeholder="商品价格" value="${product.price}"><br><!-- 图片上传在这里就先不写了--><input class="text" type="number" name="category" placeholder="商品类型(数字就好)" value="${product.category}"><br><c:if test="${product.status == 1}"><input type="radio" name="status" value="1" checked>启用<input type="radio" name="status" value="0">禁用</c:if><c:if test="${product.status == 0}"><input type="radio" name="status" value="1">启用<input type="radio" name="status" value="0" checked>禁用</c:if>
<br><input type="submit" value="修改">
</form>
</body>
</html>
第二部分修改:
service:
public void UpdateById(Product product){final SqlSession sqlSession = sqlSessionFactory.openSession();final ProductMapper mapper = sqlSession.getMapper(ProductMapper.class);mapper.updateById(product);sqlSession.commit();
}
servlet:
@WebServlet("/updateById")
public class Update extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
final Long id = Long.parseLong(request.getParameter("id"));final String title = request.getParameter("title");final String price = request.getParameter("price");final Integer category = Integer.parseInt(request.getParameter("category"));final Integer status = Integer.parseInt(request.getParameter("status"));Date gmtModified = new Date();
Product product = new Product(id,title,price,category,status,gmtModified);ProductService productService = new ProductService();productService.UpdateById(product);
request.getRequestDispatcher("/selectAll").forward(request,response);
}
@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
}
测试:




删除:不写了,jsp知道怎么写就行了
相关文章:
JavaWeb06-MVC和三层架构
目录 一、MVC模式 1.概述 2.好处 二、三层架构 1.概述 三、MVC与三层架构 四、练习 一、MVC模式 1.概述 MVC是一种分层开发的模式,其中 M:Model,业务模型,处理业务 V: View,视图,界面展…...
MySQL数据库实现增删改查基础操作
准备工作 安装mysql8.0 (安装时一定要记住用户名和密码)安装数据库可视化视图工具Navicat 请注意⚠️⚠️⚠️⚠️ a. 编程类所有软件不要安装在中文目录下 b. Navicat破解版下载安装教程:(由于文章审核提示版权问题,链接不方便给出ÿ…...
PCM和I2S区别
I2S和PCM接口都是数字音频接口,而所见的蓝牙到cpu以及codec的音频接口都是用PCM接口,是不是两个接口有各自不同的应用呢?先来看下概念。 PCM(PCM-clock、PCM-sync、PCM-in、PCM-out)脉冲编码调制,模拟语音信…...
大模型笔记:吴恩达 ChatGPT Prompt Engineering for Developers(1) prompt的基本原则和策略
1 intro 基础大模型 VS 用指令tune 过的大模型 基础大模型 只会对prompt的文本进行续写 所以当你向模型发问的时候,它往往会像复读机一样续写几个问题这是因为在它见过的语料库文本(通常大多来自互联网)中,通常会连续列举出N个问…...
设计模式 — — 单例模式
一、是什么 单例模式只会在全局作用域下创建一次实例对象,让所有需要调用的地方都共享这一单例对象 二、实现 // 单例构造函数 function CreateSingleton (name) {this.name name;this.getName(); };// 获取实例的名字 CreateSingleton.prototype.getName func…...
C++:菱形继承与虚继承
看下面这个示例代码 class A{ public: int num10; A(){cout<<"A构造"<<endl;} virtual void fun(){cout<<"A虚函数"<<endl;} };class B:public A{ public: B(){cout<<"B构造"<<endl;} void fun(){cout<…...
贡献法:USACO 2021 December Contest Bronze:孤独的照片
Farmer John 最近购入了 N 头新的奶牛,每头奶牛的品种是更赛牛(Guernsey)或荷斯坦牛(Holstein)之一。 奶牛目前排成一排,Farmer John 想要为每个连续不少于三头奶牛的序列拍摄一张照片。 然而,他…...
Java实现简单的通讯录
每日一言 泪眼问花花不语,乱红飞过秋千去。 —欧阳修- 简单的通讯录实现,跟写Java实现图书管理系统差不多,用到的知识也差不多,就当个小练习,练习一下写Java程序的手感。 Java实现图书管理系统 关于通讯录的代码都写…...
服务器数据恢复—raid5热备盘上线同步数据失败的如何恢复数据
服务器数据恢复环境&故障&分析: 一台存储上有一组由多块硬盘组建的raid5阵列,该raid5阵列中的一块硬盘掉线,热备盘自动上线同步数据的过程中,raid阵列中又有一块硬盘掉线,热备盘的数据同步被中断,r…...
探索C语言中的循环结构
循环结构是程序设计中一种重要的控制结构,它允许程序重复执行特定的代码块,直到满足某个条件为止。在C语言中,循环结构有多种形式,如for循环、while循环和do-while循环。本文将介绍C语言中的循环结构,并讨论它们的用法…...
数学建模-估计出租车的总数
文章目录 1、随机抽取的号码在总体的排序 1、随机抽取的号码在总体的排序 10个号码从小到大重新排列 [ x 0 , x ] [x_0, x] [x0,x] 区间内全部整数值 ~ 总体 x 1 , x 2 , … , x 10 总体的一个样本 x_1, x_2, … , x_{10} ~ 总体的一个样本 x1,x2,…,x10 总体的一个样…...
设计模式在芯片验证中的应用——装饰器
一、装饰器模式 装饰器模式(Decorator)是一种结构化软件设计模式,它提供了一种通过向类对象添加行为来修改类对象的方法,而不会影响同一类的其它对象行为。该模式允许在不修改抽象类的情况下添加类功能。它从本质上允许基类代码对不可预见的修改具有前瞻…...
Python 查找并高亮PDF中的指定文本
在处理大量PDF文档时,有时我们需要快速找到特定的文本信息。本文将提供以下三个Python示例来帮助你在PDF文件中快速查找并高亮指定的文本。 查找并高亮PDF中所有的指定文本查找并高亮PDF某个区域内的指定文本使用正则表达式搜索指定文本并高亮 本文将用到国产第三方…...
LEETCODE LCS 03. 主题空间
题目描述如上,这个题主要运用了DFS的思想,同时走过的路径标记为6,即可在后续的遍历中过滤掉重复的元素,其他则类似边界条件的判断和题目条件的判断,求最大值,只需要一次遍历中累加对比每一次得即可。 模板&…...
【Spring Boot 源码学习】深入应用上下文初始化器实现
《Spring Boot 源码学习系列》 深入应用上下文初始化器实现 一、引言二、往期内容三、主要内容3.1 spring-boot 子模块中内置的实现类3.1.1 ConfigurationWarningsApplicationContextInitializer3.1.2 ContextIdApplicationContextInitializer3.1.3 DelegatingApplicationConte…...
【Docker】一文趣谈Docker
🏡浩泽学编程:个人主页 🔥 推荐专栏:《深入浅出SpringBoot》《java对AI的调用开发》 《RabbitMQ》《Spring》《SpringMVC》《项目实战》 🛸学无止境,不骄不躁,知行合一 文章目录 …...
代码随想录day19(2)二叉树:二叉树的最大深度(leetcode104)
题目要求:求出二叉树的最大深度 思路:首先要区分二叉树的高度与深度。二叉树的高度是任一结点到叶子结点的距离,而二叉树的深度指的是任一节点到根节点的距离(从1开始)。所以求高度使用后序遍历(从下往上&…...
Lua中文语言编程源码-第五节,更改lcorolib.c协程库函数, 使Lua加载中文库关键词(与所有的基础库相关)
源码已经更新在CSDN的码库里: git clone https://gitcode.com/funsion/CLua.git 在src文件夹下的lcorolib.c协程库函数,Coroutine Library:表明这个C源文件实现了Lua的协程库(Coroutine Library),即提供了…...
Docker学习之数据管理(超详解析)
Docker存储资源类型: 用户在使用 Docker 的过程中,势必需要查看容器内应用产生的数据,或者需要将容器内数据进行备份,甚至多个容器之间进行数据共享,这必然会涉及到容器的数据管理: (1ÿ…...
FDTD液晶折射率各项异性表示方法
由于FDTD的数据都是沿坐标轴的,各向异性材料的参数也需要根据坐标轴来输入。 首先要了解坐标变换。 坐标变换 这里以二维坐标变化为例。 矢量下我们可以发现OP可在两个坐标系下分别表示 接下来将两个坐标相互关联,这里以Xb举例,Yb同理 注…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
Windows电脑能装鸿蒙吗_Windows电脑体验鸿蒙电脑操作系统教程
鸿蒙电脑版操作系统来了,很多小伙伴想体验鸿蒙电脑版操作系统,可惜,鸿蒙系统并不支持你正在使用的传统的电脑来安装。不过可以通过可以使用华为官方提供的虚拟机,来体验大家心心念念的鸿蒙系统啦!注意:虚拟…...
WebRTC调研
WebRTC是什么,为什么,如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...
