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

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是一种分层开发的模式&#xff0c;其中 M&#xff1a;Model&#xff0c;业务模型&#xff0c;处理业务 V&#xff1a; View&#xff0c;视图&#xff0c;界面展…...

MySQL数据库实现增删改查基础操作

准备工作 安装mysql8.0 (安装时一定要记住用户名和密码)安装数据库可视化视图工具Navicat 请注意⚠️⚠️⚠️⚠️ a. 编程类所有软件不要安装在中文目录下 b. Navicat破解版下载安装教程&#xff1a;&#xff08;由于文章审核提示版权问题&#xff0c;链接不方便给出&#xff…...

PCM和I2S区别

I2S和PCM接口都是数字音频接口&#xff0c;而所见的蓝牙到cpu以及codec的音频接口都是用PCM接口&#xff0c;是不是两个接口有各自不同的应用呢&#xff1f;先来看下概念。 PCM&#xff08;PCM-clock、PCM-sync、PCM-in、PCM-out&#xff09;脉冲编码调制&#xff0c;模拟语音信…...

大模型笔记:吴恩达 ChatGPT Prompt Engineering for Developers(1) prompt的基本原则和策略

1 intro 基础大模型 VS 用指令tune 过的大模型 基础大模型 只会对prompt的文本进行续写 所以当你向模型发问的时候&#xff0c;它往往会像复读机一样续写几个问题这是因为在它见过的语料库文本&#xff08;通常大多来自互联网&#xff09;中&#xff0c;通常会连续列举出N个问…...

设计模式 — — 单例模式

一、是什么 单例模式只会在全局作用域下创建一次实例对象&#xff0c;让所有需要调用的地方都共享这一单例对象 二、实现 // 单例构造函数 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 头新的奶牛&#xff0c;每头奶牛的品种是更赛牛&#xff08;Guernsey&#xff09;或荷斯坦牛&#xff08;Holstein&#xff09;之一。 奶牛目前排成一排&#xff0c;Farmer John 想要为每个连续不少于三头奶牛的序列拍摄一张照片。 然而&#xff0c;他…...

Java实现简单的通讯录

每日一言 泪眼问花花不语&#xff0c;乱红飞过秋千去。 —欧阳修- 简单的通讯录实现&#xff0c;跟写Java实现图书管理系统差不多&#xff0c;用到的知识也差不多&#xff0c;就当个小练习&#xff0c;练习一下写Java程序的手感。 Java实现图书管理系统 关于通讯录的代码都写…...

服务器数据恢复—raid5热备盘上线同步数据失败的如何恢复数据

服务器数据恢复环境&故障&分析&#xff1a; 一台存储上有一组由多块硬盘组建的raid5阵列&#xff0c;该raid5阵列中的一块硬盘掉线&#xff0c;热备盘自动上线同步数据的过程中&#xff0c;raid阵列中又有一块硬盘掉线&#xff0c;热备盘的数据同步被中断&#xff0c;r…...

探索C语言中的循环结构

循环结构是程序设计中一种重要的控制结构&#xff0c;它允许程序重复执行特定的代码块&#xff0c;直到满足某个条件为止。在C语言中&#xff0c;循环结构有多种形式&#xff0c;如for循环、while循环和do-while循环。本文将介绍C语言中的循环结构&#xff0c;并讨论它们的用法…...

数学建模-估计出租车的总数

文章目录 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)是一种结构化软件设计模式&#xff0c;它提供了一种通过向类对象添加行为来修改类对象的方法&#xff0c;而不会影响同一类的其它对象行为。该模式允许在不修改抽象类的情况下添加类功能。它从本质上允许基类代码对不可预见的修改具有前瞻…...

Python 查找并高亮PDF中的指定文本

在处理大量PDF文档时&#xff0c;有时我们需要快速找到特定的文本信息。本文将提供以下三个Python示例来帮助你在PDF文件中快速查找并高亮指定的文本。 查找并高亮PDF中所有的指定文本查找并高亮PDF某个区域内的指定文本使用正则表达式搜索指定文本并高亮 本文将用到国产第三方…...

LEETCODE LCS 03. 主题空间

题目描述如上&#xff0c;这个题主要运用了DFS的思想&#xff0c;同时走过的路径标记为6&#xff0c;即可在后续的遍历中过滤掉重复的元素&#xff0c;其他则类似边界条件的判断和题目条件的判断&#xff0c;求最大值&#xff0c;只需要一次遍历中累加对比每一次得即可。 模板&…...

【Spring Boot 源码学习】深入应用上下文初始化器实现

《Spring Boot 源码学习系列》 深入应用上下文初始化器实现 一、引言二、往期内容三、主要内容3.1 spring-boot 子模块中内置的实现类3.1.1 ConfigurationWarningsApplicationContextInitializer3.1.2 ContextIdApplicationContextInitializer3.1.3 DelegatingApplicationConte…...

【Docker】一文趣谈Docker

&#x1f3e1;浩泽学编程&#xff1a;个人主页 &#x1f525; 推荐专栏&#xff1a;《深入浅出SpringBoot》《java对AI的调用开发》 《RabbitMQ》《Spring》《SpringMVC》《项目实战》 &#x1f6f8;学无止境&#xff0c;不骄不躁&#xff0c;知行合一 文章目录 …...

代码随想录day19(2)二叉树:二叉树的最大深度(leetcode104)

题目要求&#xff1a;求出二叉树的最大深度 思路&#xff1a;首先要区分二叉树的高度与深度。二叉树的高度是任一结点到叶子结点的距离&#xff0c;而二叉树的深度指的是任一节点到根节点的距离&#xff08;从1开始&#xff09;。所以求高度使用后序遍历&#xff08;从下往上&…...

Lua中文语言编程源码-第五节,更改lcorolib.c协程库函数, 使Lua加载中文库关键词(与所有的基础库相关)

源码已经更新在CSDN的码库里&#xff1a; git clone https://gitcode.com/funsion/CLua.git 在src文件夹下的lcorolib.c协程库函数&#xff0c;Coroutine Library&#xff1a;表明这个C源文件实现了Lua的协程库&#xff08;Coroutine Library&#xff09;&#xff0c;即提供了…...

Docker学习之数据管理(超详解析)

Docker存储资源类型&#xff1a; 用户在使用 Docker 的过程中&#xff0c;势必需要查看容器内应用产生的数据&#xff0c;或者需要将容器内数据进行备份&#xff0c;甚至多个容器之间进行数据共享&#xff0c;这必然会涉及到容器的数据管理&#xff1a; &#xff08;1&#xff…...

FDTD液晶折射率各项异性表示方法

由于FDTD的数据都是沿坐标轴的&#xff0c;各向异性材料的参数也需要根据坐标轴来输入。 首先要了解坐标变换。 坐标变换 这里以二维坐标变化为例。 矢量下我们可以发现OP可在两个坐标系下分别表示 接下来将两个坐标相互关联&#xff0c;这里以Xb举例&#xff0c;Yb同理 注…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...