MVC模式和三层架构(附综合案例增删改查)

news2024/10/7 14:30:28

MVC模式和三层架构

MVC模式

MVC 是一种分层开发的模式,其中:

  • M:Model,业务模型,处理业务

  • V:View,视图,界面展示

  • C:Controller,控制器,处理请求,调用模型和视图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dol7M8Hq-1648441269211)(image/jsp/image-20220327212553189.png)]

控制器(serlvlet)用来接收浏览器发送过来的请求,控制器调用模型(JavaBean)来获取数据,比如从数据库查询数据;控制器获取到数据后再交由视图(JSP)进行数据展示。

MVC 好处:

  • 职责单一,互不影响。每个角色做它自己的事,各司其职。
  • 有利于分工协作。
  • 有利于组件重用

三层架构

三层架构是将我们的项目分成了三个层面,分别是 表现层业务逻辑层数据访问层

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FvZRLEdw-1648441269212)(image/jsp/image-20220327212619697.png)]

  • 数据访问层:对数据库的CRUD基本操作
  • 业务逻辑层:对业务逻辑进行封装,组合数据访问层层中基本功能,形成复杂的业务逻辑功能。例如 注册业务功能 ,我们会先调用 数据访问层selectByName() 方法判断该用户名是否存在,如果不存在再调用 数据访问层insert() 方法进行数据的添加操作
  • 表现层:接收请求,封装数据,调用业务逻辑层,响应数据

而整个流程是,浏览器发送请求,表现层的Servlet接收请求并调用业务逻辑层的方法进行业务逻辑处理,而业务逻辑层方法调用数据访问层方法进行数据的操作,依次返回到serlvet,然后servlet将数据交由 JSP 进行展示。

三层架构的每一层都有特有的包名称:

  • 表现层: com.itheima.controller 或者 com.itheima.web
  • 业务逻辑层:com.itheima.service
  • 数据访问层:com.itheima.dao 或者 com.itheima.mapper

后期我们还会学习一些框架,不同的框架是对不同层进行封装的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UhyAs5UO-1648441269213)(image/jsp/image-20220327212630913.png)]

MVC 和 三层架构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ys12WfD6-1648441269213)(image/jsp/image-20220327212644168.png)]

如上图上半部分是 MVC 模式,上图下半部分是三层架构。 MVC 模式 中的 C(控制器)和 V(视图)就是 三层架构 中的表现层,而 MVC 模式 中的 M(模型)就是 三层架构 中的 业务逻辑层 和 数据访问层。

可以将 MVC 模式 理解成是一个大的概念,而 三层架构 是对 MVC 模式 实现架构的思想。 那么我们以后按照要求将不同层的代码写在不同的包下,每一层里功能职责做到单一,将来如果将表现层的技术换掉,而业务逻辑层和数据访问层的代码不需要发生变化。

综合案例练习

需求:完成品牌数据的增删改查操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OcWTkc3J-1648441269214)(image/jsp/image-20220327212707678.png)]

这个功能我们之前一直在做,而这个案例是将今天学习的所有的内容(包含 MVC模式 和 三层架构)进行应用,并将整个流程贯穿起来。

1、环境准备

环境准备工作,我们分以下步骤实现:

  • 创建新的模块 brand_demo,引入坐标

    <dependencies>
            <!-- mybatis -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.5</version>
            </dependency>
    
            <!--mysql-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.34</version>
            </dependency>
    
            <!--servlet-->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
                <scope>provided</scope>
            </dependency>
    
            <!--jsp-->
    
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>jsp-api</artifactId>
                <version>2.2</version>
                <scope>provided</scope>
            </dependency>
    
            <!--jstl-->
            <dependency>
                <groupId>jstl</groupId>
                <artifactId>jstl</artifactId>
                <version>1.2</version>
            </dependency>
            <dependency>
                <groupId>taglibs</groupId>
                <artifactId>standard</artifactId>
                <version>1.1.2</version>
            </dependency>
    
    
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>2.2</version>
                </plugin>
            </plugins>
        </build>
    
  • 创建三层架构的包结构

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-niH2syrL-1648441269214)(image/jsp/image-20220327215027861.png)]

    作用:

    web:web相关的包

    service:服务器

    mapper:存放mybatis接口的

    pojo:放实体类

    util:放工具类

  • 数据库表 tb_brand

    -- 删除tb_brand表
    drop table if exists tb_brand;
    -- 创建tb_brand表
    create table tb_brand
    (
        -- id 主键
        id           int primary key auto_increment,
        -- 品牌名称
        brand_name   varchar(20),
        -- 企业名称
        company_name varchar(20),
        -- 排序字段
        ordered      int,
        -- 描述信息
        description  varchar(100),
        -- 状态:0:禁用  1:启用
        status       int
    );
    -- 添加数据
    insert into tb_brand (brand_name, company_name, ordered, description, status)
    values ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
           ('华为', '华为技术有限公司', 100, '华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界', 1),
           ('小米', '小米科技有限公司', 50, 'are you ok', 1);
    
    
    SELECT * FROM tb_brand;
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qGEnTX4N-1648441269215)(image/jsp/image-20220327215534355.png)]

  • 实体类 Brand

    package com.zcl.pojo;
    
    /**
     * 品牌实体类
     */
    
    public class Brand {
        // id 主键
        private Integer id;
        // 品牌名称
        private String brandName;
        // 企业名称
        private String companyName;
        // 排序字段
        private Integer ordered;
        // 描述信息
        private String description;
        // 状态:0:禁用  1:启用
        private Integer status;
    
    
        public Brand() {
        }
    
        public Brand(Integer id, String brandName, String companyName, String description) {
            this.id = id;
            this.brandName = brandName;
            this.companyName = companyName;
            this.description = description;
        }
    
        public Brand(Integer id, String brandName, String companyName, Integer ordered, String description, Integer status) {
            this.id = id;
            this.brandName = brandName;
            this.companyName = companyName;
            this.ordered = ordered;
            this.description = description;
            this.status = status;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getBrandName() {
            return brandName;
        }
    
        public void setBrandName(String brandName) {
            this.brandName = brandName;
        }
    
        public String getCompanyName() {
            return companyName;
        }
    
        public void setCompanyName(String companyName) {
            this.companyName = companyName;
        }
    
        public Integer getOrdered() {
            return ordered;
        }
    
        public void setOrdered(Integer ordered) {
            this.ordered = ordered;
        }
    
        public String getDescription() {
            return description;
        }
    
        public void setDescription(String description) {
            this.description = description;
        }
    
        public Integer getStatus() {
            return status;
        }
    
        public void setStatus(Integer status) {
            this.status = status;
        }
    
        @Override
        public String toString() {
            return "Brand{" +
                    "id=" + id +
                    ", brandName='" + brandName + '\'' +
                    ", companyName='" + companyName + '\'' +
                    ", ordered=" + ordered +
                    ", description='" + description + '\'' +
                    ", status=" + status +
                    '}';
        }
    }
    
    
  • MyBatis 基础环境

    • Mybatis-config.xml

      存放在resources文件下

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE configuration
              PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
              "http://mybatis.org/dtd/mybatis-3-config.dtd">
      <configuration>
          <!--起别名-->
          <typeAliases>
              <package name="com.zcl.pojo"/>
          </typeAliases>
      
          <environments default="development">
              <environment id="development">
                  <transactionManager type="JDBC"/>
                  <dataSource type="POOLED">
                      <property name="driver" value="com.mysql.jdbc.Driver"/>
                      <property name="url" value="jdbc:mysql:///db1?useSSL=false&amp;useServerPrepStmts=true"/>
                      <property name="username" value="root"/>
                      <property name="password" value="1234"/>
                  </dataSource>
              </environment>
          </environments>
          <mappers>
              <!--扫描mapper-->
              <package name="com.zcl.mapper"/>
          </mappers>
      </configuration>
      

      根据自己的环境修改包名和连接配置

      包扫描pojo按住ctrl+左键点击鼠标变成小手就是正确了

    • BrandMapper.xml

      在resources文件下创建包结构

      com/zcl/mapper
      
      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE mapper
              PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
              "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
      <mapper namespace="com.zcl.mapper.BrandMapper">
      	<!--映射查询数据的品牌名称和企业名称-->
          <!--映射实体属性名称和数据库名称不一致的方法-->
          <resultMap id="brandResultMap" type="brand">
              <result column="brand_name" property="brandName"></result>
              <result column="company_name" property="companyName"></result>
          </resultMap>
      </mapper>
      

      namespace报错,创建BrandMapper接口解决

    • BrandMapper接口

      com.zcl.mapper目录下

      package com.zcl.mapper;
      
      /**
       * TODO:
       *
       * @author zcl
       * @date 2022/3/27 22:00
       */
      public interface BrandMapper {
      }
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lte52Csb-1648441269216)(image/jsp/image-20220327220151339.png)]

2、查询所有数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qr75KbZ4-1648441269216)(image/jsp/image-20220327221032735.png)]

当我们点击 index.html 页面中的 查询所有 这个超链接时,就能查询到上图右半部分的数据。

对于上述的功能,点击 查询所有 超链接是需要先请后端的 servlet ,由 servlet 跳转到对应的页面进行数据的动态展示。而整个流程如下图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FvYR4Qb1-1648441269217)(image/jsp/image-20220327221011560.png)]

编写BrandMapper查询语句【Dao层】

mapper 包下创建创建 BrandMapper 接口,在接口中定义 selectAll() 方法

/**
  * 查询所有
  * @return
  */
@Select("select * from tb_brand")
@ResultMap("brandResultMap")
List<Brand> selectAll();
创建工具类减少代码重复

util包下的:SqlSessionFactoryUtils

package com.zcl.util;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class SqlSessionFactoryUtils {

    private static SqlSessionFactory sqlSessionFactory;

    static {
        //静态代码块会随着类的加载而自动执行,且只执行一次
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static SqlSessionFactory getSqlSessionFactory(){
        return sqlSessionFactory;
    }
}

编写BrandService【Service层】
package com.zcl.service;

import com.zcl.mapper.BrandMapper;
import com.zcl.pojo.Brand;
import com.zcl.util.SqlSessionFactoryUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import java.util.List;

/**
 * TODO:
 *
 * @author zcl
 * @date 2022/3/27 22:14
 */
public class BrandService {
    // 调用SqlSessionFactoryUtils根据类里面的方法【所有成员都会访问】
    SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();

    /**
     * 查询所有功能
     * @return
     */
    public List<Brand> selectAll(){
        // 获取SqlSession
        SqlSession sqlSession = factory.openSession();
        // 获取BrandMapper
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        // 调用具体的方法
        List<Brand> brandList = mapper.selectAll();
        // 释放资源
        sqlSession.close();
        return brandList;
    }
}

【Web层】

启动执行流程:启动项目默认访问index.html页面,点击a标签跳转到SelectAllServlet控制器,获取所有数据储存到域中再请求转发到brand2.jsp中遍历数据输出

创建index.html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<a href="/brand_demo/selectAllServlet">查询所有</a>
</body>
</html>

web包下创建SelectAllServlet

数据库查询的数据储存到域在中

请求转发路径

package com.zcl.web; /**
 * TODO:
 *
 * @author zcl
 * @date 2022/3/28 7:04
 */

import com.zcl.pojo.Brand;
import com.zcl.service.BrandService;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.util.List;

@WebServlet("/selectAllServlet")
public class SelectAllServlet extends HttpServlet {
    private BrandService service = new BrandService();
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 调用BrandService完成查询
        List<Brand> brands = service.selectAll();

        //2. 存入request域中
        request.setAttribute("brands",brands);

        //3. 转发到brand.jsp
        request.getRequestDispatcher("/brand2.jsp").forward(request,response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

创建brand.jsp页面获取域中的数据并使用jstl标签遍历生成表格

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="button" value="新增" id="add"><br>
<hr>
<table border="1" cellspacing="0" width="80%">
    <tr>
        <th>序号</th>
        <th>品牌名称</th>
        <th>企业名称</th>
        <th>排序</th>
        <th>品牌介绍</th>
        <th>状态</th>
        <th>操作</th>

    </tr>


    <c:forEach items="${brands}" var="brand" varStatus="status">
        <tr align="center">
            <%--<td>${brand.id}</td>--%>
            <td>${status.count}</td>
            <td>${brand.brandName}</td>
            <td>${brand.companyName}</td>
            <td>${brand.ordered}</td>
            <td>${brand.description}</td>
            <c:if test="${brand.status == 1}">
                <td>启用</td>
            </c:if>
            <c:if test="${brand.status != 1}">
                <td>禁用</td>
            </c:if>

            <td><a href="/brand-demo/selectByIdServlet?id=${brand.id}">修改</a> <a href="#">删除</a></td>
        </tr>

    </c:forEach>

</table>

<script>
    document.getElementById("add").onclick = function (){
        location.href = "/brand-demo/addBrand.jsp";
    }

</script>
</body>
</html>

启动项目默认到index页面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1adDdN9U-1648441269217)(image/jsp/image-20220328064745091.png)]

点击查询所有遍历数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Htdg2eBB-1648441269218)(image/jsp/image-20220328064807385.png)]

项目文件结构顺序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xCbe8FUV-1648441269218)(image/jsp/image-20220328095620986.png)]

3、添加所有数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CWQarrAc-1648441269219)(image/jsp/image-20220328094910248.png)]

上图是做 添加 功能流程。点击 新增 按钮后,会先跳转到 addBrand.jsp 新增页面,在该页面输入要添加的数据,输入完毕后点击 提交 按钮,需要将数据提交到后端,而后端进行数据添加操作,并重新将所有的数据查询出来。整个流程如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VC4zHOxL-1648441269220)(image/jsp/image-20220328094924175.png)]

3.1、 编写BrandMapper方法

【dao层】

BrandService 类中定义添加品牌数据方法 add(Brand brand)

/**
 * 添加数据
 * @param brand
 */
@Insert("insert into tb_brand values (null,#{brandName},#{companyName},#{ordered},#{description},#{status})")
void add(Brand brand);

【service层】

在service包下的BrandService类中添加

增删改方法都需要提交事务,再释放资源

/**
 * 添加数据
 * @param brand
 */
public void add(Brand brand){
    // 获取SqlSession
    SqlSession sqlSession = factory.openSession();
    // 获取BrandMapper
    BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
    // 调用具体的方法
    mapper.add(brand);
    // 提交事务
    sqlSession.commit();
    // 释放资源
    sqlSession.close();
}

【Web层】

在brand.jsp页面的新增按钮添加点击事件跳转到新增的页面

<script>
    document.getElementById("add").onclick = function (){
        location.href = "/brand-demo2/addBrand.jsp";
    }

</script>

创建addBrand.html页面

设置action路径在通过控制器请求转发到查询页面

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>添加品牌</title>
</head>
<body>
<h3>添加品牌</h3>
<form action="/brand-demo2/addServicelet" method="post">
    品牌名称:<input name="brandName"><br>
    企业名称:<input name="companyName"><br>
    排序:<input name="ordered"><br>
    描述信息:<textarea rows="5" cols="20" name="description"></textarea><br>
    状态:
        <input type="radio" name="status" value="0">禁用
        <input type="radio" name="status" value="1">启用<br>

    <input type="submit" value="提交">
</form>
</body>
</html>

在web包下创建AddServlet控制器

需要处理post请求乱码问题

// 处理post请求乱码问题
request.setCharacterEncoding("utf-8");
package com.zcl.web; /**
 * TODO:
 *
 * @author zcl
 * @date 2022/3/28 10:10
 */

import com.zcl.pojo.Brand;
import com.zcl.service.BrandService;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet("/addServlet")
public class AddServlet extends HttpServlet {
    // 创建BrandService对象调用方法
    private BrandService service = new BrandService();
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 处理post请求乱码问题
        request.setCharacterEncoding("utf-8");
        // 1、接收表单数据
        String brandName = request.getParameter("brandName");
        String companyName = request.getParameter("companyName");
        String ordered = request.getParameter("ordered");
        String description = request.getParameter("description");
        String status = request.getParameter("status");
        // 2、封装为一个Brand对象
        Brand brand = new Brand();
        brand.setBrandName(brandName);
        brand.setCompanyName(companyName);
        brand.setOrdered(Integer.parseInt(ordered));
        brand.setDescription(description);
        brand.setStatus(Integer.parseInt(status));
        // 3、调用add添加方法
        service.add(brand);
        // 4、转发到查询所有的jsp页面
        request.getRequestDispatcher("/selectAllServlet").forward(request,response);

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sOKxV9Lh-1648441269220)(image/jsp/image-20220328102609512.png)]

文件编写顺序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2cIALcOy-1648441269221)(image/jsp/image-20220328103226916.png)]

4、修改数据回填显示

4.1、数据回填显示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CDgWuQGP-1648441269222)(image/jsp/image-20220328104658951.png)]

上图就是回显数据的效果。要实现这个效果,那当点击 修改 按钮时不能直接跳转到 update.jsp 页面,而是需要先带着当前行数据的 id 请求后端程序,后端程序根据 id 查询数据,将数据存储到域对象中跳转到 update.jsp 页面进行数据展示。整体流程如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7RzuBQwI-1648441269222)(image/jsp/image-20220328104715465.png)]

4.2、编写BrandMapper方法【Dao层】

BrandMapper 接口,在接口中定义 selectById(int id) 方法

/**
 * 根据id查询信息
 * @param id
 * @return
 */
@Select("select * from tb_brand where id = #{id}}")
@ResultMap("brandResultMap")
Brand selectById(int id);
4.3、编写BrandService方法【Service层】

BrandService 类中定义根据id查询数据方法 selectById(int id)

/**
 * 根据id查询信息回填表单页面
 * @return
 */
public Brand selectById(int id){
    // 获取SqlSession
    SqlSession sqlSession = factory.openSession();
    // 获取BrandMapper
    BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
    // 调用具体的方法
    Brand brandList = mapper.selectById(id);
    // 释放资源
    sqlSession.close();
    return brandList;
}
4.4、 编写servlet控制器【Web层】

改造修改页面,点击修改跳转查询数据回填

<td><a href="/brand-demo2/selectByIdServlet?id=${brand.id}">修改</a> <a href="#">删除</a></td>

创建SelectByIdServlet根据id查询信息控制器,并请求转发到修改页面

package com.zcl.web; /**
 * TODO:
 *
 * @author zcl
 * @date 2022/3/28 7:04
 */

import com.zcl.pojo.Brand;
import com.zcl.service.BrandService;

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.util.List;

@WebServlet("/selectByIdServlet")
public class SelectByIdServlet extends HttpServlet {
    private BrandService service = new BrandService();
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1、接收id
        String id = request.getParameter("id");
        // 2、调用Servlet根据id查询数据
        Brand brand = service.selectById(Integer.parseInt(id));
        // 3、数据储存到request域中
        request.setAttribute("brand",brand);
        // 4、请求转发到修改回填页面
        request.getRequestDispatcher("/update.jsp").forward(request,response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

创建修改页面update.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>修改品牌</title>
</head>
<body>
<h3>修改品牌</h3>
<form action="/brand-demo2/addServlet" method="post">
    品牌名称:<input name="brandName" value="${brand.brandName}"><br>
    企业名称:<input name="companyName" value="${brand.companyName}"><br>
    排序:<input name="ordered" value="${brand.ordered}"><br>
    描述信息:<textarea rows="5" cols="20" name="description">${brand.description}</textarea><br>
    状态:
        <c:if test="${brand.status == 0}">
        <input type="radio" name="status" value="0" checked>禁用
        <input type="radio" name="status" value="1">启用<br>
        </c:if>
    <c:if test="${brand.status == 1}">
        <input type="radio" name="status" value="0">禁用
        <input type="radio" name="status" value="1" checked>启用<br>
    </c:if>
    <input type="submit" value="提交">
</form>
</body>
</html>

启动项目效果展示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fhcXy3bB-1648441269223)(image/jsp/image-20220328113505399.png)]

5、修改数据回填显示

在修改页面进行数据修改,点击 提交 按钮,会将数据提交到后端程序,后端程序会对表中的数据进行修改操作,然后重新进行数据的查询操作。整体流程如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gRKTjSBp-1648441269223)(image/jsp/image-20220328113801683.png)]

5.1、 编写BrandMapper方法【Dao层】

BrandMapper接口

/**
  * 修改
  * @param brand
  */
@Update("update tb_brand set brand_name = #{brandName},company_name = #{companyName},ordered = #{ordered},description = #{description},status = #{status} where id = #{id}")
void update(Brand brand);
5.2、 编写BrandService方法【service层】

BrandService 类中定义根据id查询数据方法 update(Brand brand)

/**
 * 修改数据
 * @param brand
 */
public void update(Brand brand){
    // 获取SqlSession
    SqlSession sqlSession = factory.openSession();
    // 获取BrandMapper
    BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
    // 调用具体的方法
    mapper.update(brand);
    // 提交事务
    sqlSession.commit();
    // 释放资源
    sqlSession.close();
}
5.3、改造update.jsp页面【web层】
<form action="/brand-demo2/updateServlet" method="post">
    <input type="hidden" name="id" value="${brand.id}">
    品牌名称:<input name="brandName" value="${brand.brandName}"><br>
    企业名称:<input name="companyName" value="${brand.companyName}"><br>
    排序:<input name="ordered" value="${brand.ordered}"><br>
    描述信息:<textarea rows="5" cols="20" name="description">${brand.description}</textarea><br>
    状态:
        <c:if test="${brand.status == 0}">
        <input type="radio" name="status" value="0" checked>禁用
        <input type="radio" name="status" value="1">启用<br>
        </c:if>
        <c:if test="${brand.status == 1}">
            <input type="radio" name="status" value="0">禁用
            <input type="radio" name="status" value="1" checked>启用<br>
        </c:if>
    <input type="submit" value="提交">
</form>
5.4、创建UpdateServlet控制器【web层】

web包下

package com.zcl.web; /**
 * TODO:
 *
 * @author zcl
 * @date 2022/3/28 10:10
 */

import com.zcl.pojo.Brand;
import com.zcl.service.BrandService;

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;

@WebServlet("/updateServlet")
public class UpdateServlet extends HttpServlet {
    // 创建BrandService对象调用方法
    private BrandService service = new BrandService();
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 处理post请求乱码问题
        request.setCharacterEncoding("utf-8");
        // 1、接收表单数据
        String id = request.getParameter("id");
        String brandName = request.getParameter("brandName");
        String companyName = request.getParameter("companyName");
        String ordered = request.getParameter("ordered");
        String description = request.getParameter("description");
        String status = request.getParameter("status");
        // 2、封装为一个Brand对象
        Brand brand = new Brand();
        brand.setId(Integer.parseInt(id));
        brand.setBrandName(brandName);
        brand.setCompanyName(companyName);
        brand.setOrdered(Integer.parseInt(ordered));
        brand.setDescription(description);
        brand.setStatus(Integer.parseInt(status));
        // 3、调用修改方法
        service.update(brand);
        // 4、转发到查询所有的jsp页面
        request.getRequestDispatcher("/selectAllServlet").forward(request,response);

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

6、删除数据

6.1、在 BrandService 类中定义根据id查询数据方法 selectById(int id) 【Dao层】

/**
 * 删除
 * @param id
 */
@Update("delete from tb_brand where id = #{id}")
void deldate(int id);

6.2、在service包下调用方法【service层】

/**
 * 根据id删除信息
 * @return
 */
public void deldate(int id){
    // 获取SqlSession
    SqlSession sqlSession = factory.openSession();
    // 获取BrandMapper
    BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
    // 调用具体的方法
    mapper.deldate(id);
    // 提交事务
        sqlSession.commit();
    // 释放资源
    sqlSession.close();
}

6.3、【Web层】

修改brand2.jsp页面的删除标签

<td><a href="/brand-demo2/selectByIdServlet?id=${brand.id}">修改</a> <a href="/brand-demo2/delByIdServlet?id=${brand.id}">删除</a></td>

创建DelServlet删除控制器

@WebServlet("/delByIdServlet")
public class DelServlet extends HttpServlet {
    // 创建BrandService对象调用方法
    private BrandService service = new BrandService();
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1、接收表单数据
        String id = request.getParameter("id");
        // 3、调用修改方法
        service.deldate(Integer.parseInt(id));
        // 4、转发到查询所有的jsp页面
        request.getRequestDispatcher("/selectAllServlet").forward(request,response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/574633.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【ISO14229_UDS刷写】-5-$38诊断服务RequestFileTransfer理论部分

总目录&#xff1a;&#xff08;单击下方链接皆可跳转至专栏总目录&#xff09; 《UDS/OBD诊断需求编辑工具》总目录https://blog.csdn.net/qfmzhu/article/details/123697014 目录 1 $0x38 RequestFileTransfer诊断服务描述 2 0x38服务请求消息 2.1 0x38服务请求消息定义…

MongoDB window安装教程

官网下载 MongoDB&#xff1a;https://www.mongodb.com/try/download/community MongoDB shell脚本&#xff1a;https://www.mongodb.com/try/download/shell&#xff0c;下载后解压到MongoDB安装目录创建数据库文件的存放位置 在data文件夹下创建 db 文件夹&#xff08;启动 …

【composer】如何在本地开发、调试Composer包

1、准备工作 创建两个空文件夹 |- TestProject # 用于composer引入测试 |- TestPackage # composer的自定义扩展包1.1 初始化 在TestProject和TestPackage分别执行&#xff1a; composer init一路默认或者自己按需修改引导中的参数完成composer初始化 例如&#xff1a; Pa…

C++11常用的一部分新特性

C11 统一的列表初始化&#xff5b;&#xff5d;初始化std::initializer_list 声明autodecltypenullptr STL中一些变化新容器已有容器的新接口 右值引用和移动语义左值引用和右值引用右值引用使用场景和意义右值引用引用左值及其一些更深入的使用场景分析完美转发 新的类功能默认…

【ISO14229_UDS刷写】-4-$37诊断服务RequestTransferExit理论部分

总目录&#xff1a;&#xff08;单击下方链接皆可跳转至专栏总目录&#xff09; 《UDS/OBD诊断需求编辑工具》总目录https://blog.csdn.net/qfmzhu/article/details/123697014 目录 1 $0x37 RequestTransferExit诊断服务描述 2 0x37服务请求消息 2.1 0x37服务请求消息定义…

经典 SQL 数据库笔试题及答案整理

马上又是金三银四啦&#xff0c;有蛮多小伙伴在跳槽找工作&#xff0c;但对于年限稍短的软件测试工程师&#xff0c;难免会需要进行笔试&#xff0c;而在笔试中&#xff0c;基本都会碰到一道关于数据库的大题&#xff0c;今天这篇文章呢&#xff0c;就收录了下最近学员反馈上来…

PLX31-EIP-MBTCP 以太网/IP到Modbus TCP/IP

PLX31-EIP-MBTCP ProSoft Technology的EtherNet/IP to Modbus TCP/IP通信网关允许在支持EtherNet/IP的控制器或设备与Modbus TCP/IP控制器或设备之间进行高速双向数据传输。 我们的Modbus TCP/IP驱动程序具有多种客户端和服务器功能&#xff0c;可实现更快的数据传输。此外&a…

策略路由+静态路由+ip link+healthcheck检测外网物理链路提高网络的可靠性

一、适用环境 1、外网链路有防火墙Firewall出口&#xff0c;外网也有路由器Router出口。 2、用户量大需要多条外网链路负载均衡&#xff0c;多条链路也可以互为主备。 3、有ip专线网络&#xff08;上下行对称&#xff09;与拨号光纤&#xff08;上下行非对称&#xff09;网络配…

PFEA112-65 3BSE050091R65 满足正确的机械和电气安装

力传感器的工作原理对其性能有很大影响。它还影响整个称重传感器的刚性和无振动程度&#xff0c;以及其稳健性和过载耐受性。所有这些因素都会影响卷筒纸加工机械。ABB的Pressductor传感器技术由于当称重传感器受到机械力时的电磁场。 这是一个操作起源于冶金现象的原理力改变…

AI:探究下前端组件化设计的实现方法及其重要性

文章目录 1. 什么是前端组件化设计1.1 定义前端组件1.2 什么是组件化设计 2. 组件化设计的重要性2.1 提高开发效率2.2 降低维护成本2.3 促进代码复用 3. 组件化设计的原则和模式3.1 单一职责原则3.2 可复用性原则3.3 可拆分性原则3.4 可扩展性原则3.5 微型模式3.6 组件库模式3.…

Chat-GPT 聚合平台 Poe:集成多个 AI 聊天机器人

Chat-GPT 聚合平台 Poe&#xff1a;集成多个 AI 聊天机器人 介绍 Poe 是知名问答社区 Quora 推出的 AI 平台——开放探索平台 (Platform for Open Exploration, Poe)。Poe 集成了多个基于大型语言模型的聊天机器人&#xff0c;包括 ChatGPT&#xff0c;以及 Sage、Claude、Dr…

代码随想录算法训练营15期 Day 3 | 203.移除链表元素 、707.设计链表 、206.反转链表

今日任务 链表理论基础 203.移除链表元素 707.设计链表 206.反转链表 链表理论基础 链表是一种通过指针串联在一起的线性结构&#xff0c;每一个节点由两部分组成&#xff0c;一个是数据域一个是指针域&#xff08;存放指向下一个节点的指针&#xff09;&#xff0c;最后…

代码随想录算法训练营第五十三天 | 子序列系列2

1143.最长公共子序列 文档讲解&#xff1a;代码随想录 (programmercarl.com) 视频讲解&#xff1a;动态规划子序列问题经典题目 | LeetCode&#xff1a;1143.最长公共子序列_哔哩哔哩_bilibili 状态&#xff1a;dp定义想不到&#xff0c;看了dp定义能写出后面部分。 思路 动规…

ab压力测试工具使用

AB测试工具使用 参考网址&#xff1a; https://pdai.tech/md/devops/linux/linux-ab-test.html 推荐 java 体系学习网址 https://pdai.tech/ 安装 基于 Linux 操作系统 &#xff0c; 在 centos7 中安装 ab 测试工具 yum -y install httpd-tools测试安装是否成功&#xff1a;…

【ISO14229_UDS刷写】-1-$34诊断服务RequestDownload理论部分

总目录&#xff1a;&#xff08;单击下方链接皆可跳转至专栏总目录&#xff09; 《UDS/OBD诊断需求编辑工具》总目录https://blog.csdn.net/qfmzhu/article/details/123697014 目录 1 $0x34 RequestDownload诊断服务描述 2 0x34服务请求消息 2.1 0x34服务请求消息定义 2.…

11.TMS320C5509V+Win10+CCS8开发环境搭建

一、简介 众所周知&#xff0c;相较于TMS320F28335&#xff0c;TMS320C5509V属于较老的平台&#xff0c;在新版本的CCS版本上支持一直是一个问题。 最基本的问题便是&#xff0c;无法新建基础工程。各开发版厂商提供的例程无法在CCS8上使用&#xff0c;只支持CCS3.3环境&…

chatgpt赋能python:Python分词库的介绍

Python 分词库的介绍 Python 分词库是一个用于将一段自然语言文本分解为单词序列的工具。这对于自然语言处理和文本分析来说是一个重要的工具。Python 分词库可以将大量的文本数据转化成机器可读的、易于处理的数据。在 SEO 优化方面&#xff0c;Python 分词库也起到了关键的作…

华为云安装与使用

华为云安装与使用 文章目录 华为云安装与使用下载地址修改 /etc/hosts设置 AK/SK/Endpoint查看桶名查看桶内文件通过 ./obsutil config -interactive 方式设置配置文件问题 obsutil 命令行快速使用操作步骤操作桶上传文件约束与限制参数说明更多上传示例 删除下载对象 Referenc…

数据库基础——2.MySQL的卸载安装及相关环境的配置

这篇文章我们来说一下MySQL的下载、安装、相关环境配置、可能遇见的问题及其解决方案、卸载等操作。 目录 1.查看已安装的 1.1 命令提示窗口下查看 1.2 文件目录下查看 2.Mysql的卸载 2.1卸载mysql 2.2 清理其他文件 3.MySQL的下载 3.1 介绍 3.2 软件下载 3.3 软件安…

python求解一阶线性偏微分方程通解举例

python求解一阶线性偏微分方程的通解举例 Python求解偏微分方程也是其一个应用方面&#xff0c;下面举例说明。 一、问题&#xff1a; 求一阶线性偏微分方程 x ∂ f ( x , y ) ∂ x − y ∂ f ( x , y ) ∂ y y 2 f ( x , y ) y 2 x\frac{{\partial f(x,y)}}{{\partial x}…