JavaWeb技术栈 之 HTTP Tomcat Servlet JSP MVC 简单学习

373 阅读13分钟

1、B/S 架构以及 C/S 架构

B/S 架构:服务器端进行修改之后,方便维护 在这里插入图片描述

2、HTTP

浏览器与服务器之间进行数据传输的一种协议 在这里插入图片描述

2.1 请求数据的格式

在这里插入图片描述

get 在请求行中请求参数;没有请求体; post 在请求体中请求参数,一般使用 post 即可,作用都是向服务器发送数据;

2.2 响应数据的格式

在这里插入图片描述

2.3 常见的状态码

在这里插入图片描述

在这里插入图片描述 需要了解 200 运行成功 404 请求的资源不存在 或者输入 URL 存在错误 500 查看服务器端的 Java 代码 其他的查看相关文档即可

3、Tomcat

Tomcat 是一个服务器软件,没有这个服务器软件的话,对于 HTTP 里面的请求协议以及响应协力里面的内容需要我们自己写代码进行解析,实现起来是十分麻烦的; 使用了 Tomcat 服务器软件,可以更加的专注于逻辑代码的开发,而不是开发服务器代码的开发; 屏蔽了底层和HTTP内容打交道的代码,简化了开发; 在这里插入图片描述 可以使用类似于 Tomcat 服务器软件进行项目的部署,其他计算机可以使用 ip + 端口 + 路径 从而进行资源的访问;

3.1 了解Tomcat

就是一个服务器软件; 下载下来,将自己的项目安放置在 Tomcat 指定的文件夹中,在 bin 目录下,执行相应的命令(startup)(关闭的时候使用shutdown),启动服务,本台计算机就可以充当服务器了;

支持的 Servlet/JSP 少量的 JavaEE 规范是一个轻量级的 Web 服务器软件; 在这里插入图片描述

3.2 Web 服务器的作用?

1、封装了 HTTP 协议操作,简化了开发 2、可以将 web 项目部署在服务器中,对外提提供浏览服务

Tomcat 是一个轻量级的 web 服务器软件,支持 Servlet/JSP 少量的 JavaEE规范,也叫做 Web 容器,Servlet 容器;

3.3 idea maven + web 项目创建

在这里插入图片描述

3.3.1 打包出现错误解决

问题描述

webxml attribute is required (or pre-existing WEB-INF/web.xml if executing in update mode)

产生原因

maven的web项目默认的webroot是在src\main\webapp。如果在此目录下找不到web.xml就抛出以上的异常。

解决方式如下,在 pop 文件中进行配置:

<packaging>war</packaging>

<!--    配置的 web.xml 的位置需要正确-->
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>3.3.1</version>
            <configuration>
                <webXml>web\WEB-INF\web.xml</webXml>
            </configuration>
        </plugin>
    </plugins>
</build>

3.3.2 idea 里面创建出来的目录结构

在这里插入图片描述

3.4 使用 idea 进行项目的创建

使用骨架的创建方式 使用骨架使用的是 maven 里面的 webapp; 在这里插入图片描述

不使用骨架创建出来的方式 在这里插入图片描述

3.5 idea 集成 Tomcat

1、集成本地 Tomcat

在这里插入图片描述

2、maven 插件

缺点是:目前只能集成 Tomcat7 的版本,更多的版本使用本地集成即可 在这里插入图片描述

3 maven 配置 Tomcat 的 pom 文件配置

使用 maven 里面配置的 Tomcat 就是 Tomcat 的简单集成,方便与快速的启动与配置;

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>TomcatWebapp</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--
    package 打包方式
      1、使用 jar 包的打包方式 默认值
      2、使用 war 包的打包方式 需要自己配置
-->
    <packaging>war</packaging>

    <build>
        <plugins>
            <!-- Tomcat 插件 -->
            <!-- 这个插件是为了 打包成为 war 的时候不报错-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.1</version>

                <!-- 这个是为了打包成为 war 包时候不报错,配置 web.xml 文件的位置-->
                <configuration>
                    <!-- 直接拷贝的 contents 目录 配置到这个地方-->
                    <webXml>src/main/webapp/WEB-INF/web.xml</webXml>
                </configuration>
            </plugin>

            <!-- 这个插件是为了配置 Tomcat 在 maven 中直接右键启动 在 maven 中配置的 tomcat -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <port>80</port>
                    <path>/</path>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

4、Servlet

4.1 定义

Servlet 是 Java 提供的一个动态 web 资源开发技术,是一个开发技术

在这里插入图片描述

什么是动态资源? 所谓的静态资源就是类似 html 这种文件,所有访问的人看到的效果是一致的,是不会发生变化的; 而动态资源是随着访问的人的不同,其访问的结果是不同的,目前的大数据中,可以精准的推动广告,就是一种动态的开发技术;

4.2 快速入门

在这里插入图片描述 注意:在 pom 文件中配置的 标签中是需要配置 provide 的,这是在测试以及编译环境有效,在运行环境中无效的;不配置这个的话启动Servlet 的 service() 服务会出现错误

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>

4.3 Servlet 执行流程

在这里插入图片描述 在这里插入图片描述

4.4 Servlet 生命周期

Servlet 对象是什么时候被创建的?

对象的生命周期: 对象的生命周期值得是一个对象从被创建到被销毁的整个过程; 在这里插入图片描述 只有当第一次被访问的时候,这个对象才被创建的,其他的时间是没有创建出来的;

4.4.1 Servlet 里面方法的生命周期

// 配置访问路径,方便程序的访问
@WebServlet(urlPatterns = "/demo2",loadOnStartup = 1)
public class ServletDemo2 implements Servlet {
    // 实现了接口,要将接口中的抽象方法全部实现
    // 将来的 Servlet 被访问的时候 service() 方法是会自动被访问执行

    /**
     * 初始化的方法
     *      调用时机 默认情况下 Servlet 第一次 被访问的时候被调用,被调用之前创建了对象
     *              在类上面配置了 loadOnStartup 的时候,可以考虑在 Tomcat 启动的时候,开始服务
     *      调用次数 调用一次 在控制台上面只能看到一次
     *
     * @param servletConfig
     * @throws ServletException
     */
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init...");
    }

    /**
     * 提供服务
     *      调用时机 每一次 访问servlet 的时候,就是界面刷新的时候
     *      调用次数 可以调用多次,服务是多次的不是一次性的
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        System.out.println("Hello Servlet");
    }

    /**
     *      调用时机 内存释放的时候,服务器关闭的时候,Servlet 对象会被销毁,调用这个方法
     *      调用次数 一次
     */
    @Override
    public void destroy() {
        System.out.println("destroy...");
    }

4.4.2 Servlet 方法的介绍

在这里插入图片描述

4.5 Servlet 体系结构

在这里插入图片描述

4.5.1 HttpServlet 为什么根据请求方式的不同从而访问不同的方法?

方法的分发 在 http 中 post 以及 get 请求的参数的位置是不同的,get 在请求行中,post 在请求体中,所以需要请求方式的不同,进行分别的处理;

请求的方式传递到 Servlet 的 service() 方法的时候,可以获取到表单中提交的是 get 方法还是 post 方法,从而在 HttpServlet 中分发出来两个方法,得到不同的参数;

4.5.2 HttpServlet 的原理

简单来说就是对于 Servlet 的继承以及发展,在这个里面将前端传递进来的请求,分流成为两个方法,一个是 doGet() 一个是doPost() 方法,两个不同的方法,接收不同的请求,处理不同的请求;

4.5.3 怎么调用?

根据 HttpServlet 里面封装的内容,获取到不同的请求,调用了不同的方法,具体调用的实现步骤可以查看源代码;

4.5.4 HttpServlet 小结

在这里插入图片描述

4.6 Servlet urlPattern 配置

Servlet 在想要被访问的时候,是需要配置访问路径的,不配置的话,是没有办法定位到 Java 代码的,也就执行不到相关的逻辑 在这里插入图片描述

/**
 * Servlet 使用多路径进行配置
 *      一个 Servlet 配置多路径
 */

@WebServlet(urlPatterns = {"/demo7","/demo8"})
public class ServletDemo7 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet...");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doPost...");
    }
}

4.6.1 精确匹配

在 @WebServlet 里面配置的什么路径,就使用什么样的路径进行访问; 在这里插入图片描述

4.6.2 目录匹配

在这里插入图片描述

当一个目录既满足精确匹配又满足目录匹配的时候,优先访问精确匹配,精确匹配的优先级别高一些;

4.6.3 扩展名匹配

在这里插入图片描述 可以访问到后缀是 .do 的任意文件

4.6.4 任意匹配

在这里插入图片描述

无论写成什么。都是可以匹配的;

因为其会覆盖掉Servlet 里面本身的配置,导致一些资源无法访问,所以一般不建议配置 "/" 以及 "/*"

4.7 xml 配置方式编写 Servlet

在这里插入图片描述 一种过时的书写方法,比较麻烦,建议使用注解的方式,简单明了;

5、Request(请求)

在这里插入图片描述

5.1 Request 继承体系

在这里插入图片描述 查阅文档的时候,查阅 HttpServletRequest 接口即可

5.2 Request 获取请求数据

在这里插入图片描述

@WebServlet("/requestDemo1")
public class RequestDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取请求方式
        String method = req.getMethod();
        System.out.println(method);

        // 获取虚拟目录
        String contextPath = req.getContextPath();
        System.out.println(contextPath);

        // 获取 URL
        StringBuffer requestURL = req.getRequestURL();
        System.out.println(requestURL);

        // 获取 URI
        String requestURI = req.getRequestURI();
        System.out.println(requestURI);

        // 获取请求参数
        String queryString = req.getQueryString();
        System.out.println(queryString);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

5.3 Request 通用(统一的)的方式获取请求参数

在这里插入图片描述

package com.luobin.web;

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.Map;


@WebServlet("/req2")
public class RequestDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // get 请求逻辑
        System.out.println("get...");

        // 获取 key
        Map<String, String[]> map = req.getParameterMap();
        for (String key : map.keySet()) {
            System.out.print(key + ":");

            // 获取 value
            String[] values = map.get(key);
            for (String value : values) {
                System.out.print(value + " ");
            }
        }

        // 获取前端传递进来的数据(可能是数字或者文件)
        System.out.println("---------");
        String[] hobbies = req.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // post 请求逻辑
        doGet(req, resp);
    }
}

5.4 Request 请求数据的一般方式

在 doPost 里面写上 doPost(); 在这里插入图片描述

5.5 请求参数中乱码问题解决

post 是设置流的编码,所以是可以解决的; 在这里插入图片描述

@WebServlet("/req4")
public class RequestDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 输入的中文可能存在乱码的问题,进行解决
        // 因为字符集是不一样的,所以在这里是需要重新设定编码的
        request.setCharacterEncoding("UTF-8");

        // 前端得到输入的参数
        String username = request.getParameter("username");
        System.out.println(username);
    }

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

get 不是流的方式传递参数的;

为什么乱码产生的原因? 编码,解码的字符集是不一样的; 在这里插入图片描述

5.5.1 小结 解决中文乱码的问题

在这里插入图片描述

Request 请求转发

在这里插入图片描述

相当于流水线上面的东西,可以进行数据共享,转到其他的 服务进行处理;

@WebServlet("/req5")
public class RequestDemo5 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("demo5...");

        // 存储数据
        request.setAttribute("message","hello");

        // 请求转发
        // 请求转发的路径
        request.getRequestDispatcher("/req6").forward(request, response);
    }

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

@WebServlet("/req6")
public class RequestDemo6 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取其他的 Servlet 发送过来的数据
        Object msg = request.getAttribute("message");
        System.out.println(msg);

        System.out.println("demo6...");
    }

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

特点: 1、浏览器地址栏的路径是不会发生变化的 2、只能转发到当前服务器的内部资源 3、一次请求,可以在转发的资源间使用 request 共享数据

6、Response(响应)

在这里插入图片描述

6.1 Response 设置响应数据功能介绍

在这里插入图片描述

6.2 Response 完成重定向

在这里插入图片描述

重定向也是资源的跳转方式,和请求转发不同的是,重定向在告诉浏览器本身,处理不了,然后,让浏览器找到能处理的地方;请求转发是直接在资源内部进行了转发

6.3 重定向和请求转发之间的区别

在这里插入图片描述

6.4 路径问题 加不加虚拟目录?

在这里插入图片描述

判断的依据是浏览器使用加上虚拟目录,服务端使用,不需要添加虚拟目录;

降低耦合,可以动态的获取虚拟目录,所谓的虚拟目录就是假设是这个项目的根目录;

在这里插入图片描述

6.5 Response 响应字符数据

在这里插入图片描述

/**
 * 响应字符数据,设置字符数据的响应体
 */

@WebServlet("/resp3")
public class response3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 防止出现乱码,可以解析 html 文档的设置 设置响应格式以及字符集
        response.setContentType("text/html;charset = utf-8");

        System.out.println("resp3...");
        // 获取字符输出流

        PrintWriter writer = response.getWriter();

        writer.write("你好");
        writer.write("<h1>aaa<h1>");
    }

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

6.6 Response 响应字节数据

在这里插入图片描述

/**
 * 相应字节数据,设置字节数据的响应体
 */

@WebServlet("/resp4")
public class response4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 读取文件
        FileInputStream fis = new FileInputStream("img.png");

        // 获取字节输出流
        ServletOutputStream os = response.getOutputStream();

        // 完成流的 copy
//        byte[] buff = new byte[1024];
//        int len = 0;
//
//        while ((len = fis.read(buff)) != -1) {
//            os.write(buff, 0, len);
//        }

        // 完成拷贝,输入流,输出流作为参数输到下面的方法中即可
        // 使用 common-io 可以简化 流的代码的书写
        IOUtils.copy(fis, os);

        fis.close();
    }

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

用户登录以及注册的代码实现

用户登录

在这里插入图片描述

在这里插入图片描述

用户注册

在这里插入图片描述

7、JSP

在这里插入图片描述 因为想要进行动态 web 的开发,不可避免的在 html 中修改一些数据,改的时候,在后端修改,想要在修改完成后在前端显示,那么不使用 jsp 的话,会使得在 Servlet 中 编写代码变得非常麻烦以及复杂,引入了 jsp 之后,可以在 Servlet 中存在 Servlet 代码以及 html 代码,一定程度上简化了代码;

7.1 jsp快速入门

在这里插入图片描述

7.2 jsp 原理

在这里插入图片描述

7.3 jsp 脚本

在这里插入图片描述

<%@ page import="com.luobin.pojo.Brand" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %><%--
  Created by IntelliJ IDEA.
  User: yimeng
  Date: 2022/3/12
  Time: 5:06 下午
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%
    // 查询数据库
    List<Brand> brands = new ArrayList<Brand>();
    brands.add(new Brand(1, "三只松鼠", "三只松鼠", 100, "三只松鼠,好吃不上火", 1));
    brands.add(new Brand(2, "优衣库", "优衣库", 200, "优衣库,服适人生", 0));
    brands.add(new Brand(3, "小米", "小米科技有限公司", 1000, "为发烧而生", 1));
%>

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

            </tr>

            <%
                for (int i = 0; i < brands.size(); i++) {
                    Brand brand = brands.get(i);
            %>

            <tr align="center">
                <td><%=brand.getId()%>
                </td>
                <td><%=brand.getBrandName()%>
                </td>
                <td><%=brand.getCompanyName()%>
                </td>
                <td><%=brand.getOrdered()%>
                </td>
                <td><%=brand.getDescription()%>
                </td>
                <td><%=brand.getStatus()%>
                </td>
                <td><a href="#">修改</a> <a href="#">删除</a></td>
            </tr>

            <%
                }
            %>
        </table>

    </body>
</html>

在这里插入图片描述 在这里插入图片描述

7.4 EL 表达式

是为了获取数据,为了下一步的为 JSTL 对数据进行判断,想要获取数据,前提是需要将数据放置在域中 在这里插入图片描述

@WebServlet("/el-demo1")
public class ServletEL1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1、准备数据
        List<Brand> brands = new ArrayList<Brand>();
        brands.add(new Brand(1, "三只松鼠", "三只松鼠", 100, "三只松鼠,好吃不上火", 1));
        brands.add(new Brand(2, "优衣库", "优衣库", 200, "优衣库,服适人生", 0));
        brands.add(new Brand(3, "小米", "小米科技有限公司", 1000, "为发烧而生", 1));

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

        // 3 转发到 el-demo.jsp 中
        request.getRequestDispatcher("/el-demo.jsp").forward(request,response);

    }

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

7.5 JSTL 标签

直接在 jsp 里面书写代码,对于项目的维护是十分不方便的,因为前端可能不懂 Java 代码,并且在 jsp 里面书写的 Java 代码经常需要代码的截断,读取以及书写都是不方便的,所以在 jsp 里面的判断代码以及循环代码,使用 jstl 标签代替,又可以简化一定的代码 在这里插入图片描述 在这里插入图片描述

在这里插入图片描述

7.6 MVC 模式和三层架构

在这里插入图片描述 在这里插入图片描述

表现层:web 层或者叫做 controller 层

业务逻辑层:service 层 数据访问层:dao 层 业务了逻辑可以和数据访问放在一起,因为在执行业务逻辑的时候,一定上需要访问数据的;

三层架构可以说是对于三层模型的一种物理实现;

7.6.1 MVC 和 三层架构区别

在这里插入图片描述

M ------业务逻辑层 数据访问层 V C ------表现层

7.7 案例 使用 MVC 进行数据的 CRUD

 使用

7.7.1 创建的项目目录

在这里插入图片描述

7.7.2 三层架构下的查询设计

在这里插入图片描述

7.7.3 三层架构下的添加数据

在这里插入图片描述

web层

@WebServlet("/AddServlet")
public class AddServlet extends HttpServlet {

    private BrandService service = new BrandService();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 配置可能存在的乱码问题
        request.setCharacterEncoding("utf-8");

        // 1、接收表单中提交的数据,封装成为一个 Brand 对象,接收表单参数,封装成为对象的目的是将数据添加到数据库中
        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");

        Brand brand = new Brand();
        brand.setBrandName(brandName);
        brand.setCompanyName(companyName);
        brand.setDescription(description);
        // 封装的对象的时候,因为这个数据从前端获取过来是 String ,在这里需要进行数据类型的转换
        brand.setStatus(Integer.parseInt(status));
        brand.setOrdered(Integer.parseInt(ordered));

        // 调用 service() 完成数据的添加
        service.add(brand);

        // 转发到查询所有的 Servlet
        request.getRequestDispatcher("/selectAllServlet").forward(request,response);
    }

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

service 层

public class BrandService {
    // 通过提前写好的 utils 里面的工具创建一次工厂,减少系统的资源浪费
    SqlSessionFactory factory = SqlSessionFactoryUtil.getSqlSessionFactory();

    /**
     * 查询所有
     * @return
     */
    public List<Brand> selectAll() {
        // 调用 BrandMapper.selectAll()

        // 获得 SqlSessionFactory() 创建 sqlSession 对象方便执行 sql 语句
//        SqlSessionFactory factory = SqlSessionFactoryUtil.getSqlSessionFactory();

        SqlSession sqlSession = factory.openSession();

        // 获取 BrandMapper
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);

        // 调用方法
        List<Brand> brands = mapper.selectAll();

        // 因为知识查询操作,所以是不需要提交事务的,知识将资源进行关闭即可
        sqlSession.close();

        return brands;
    }

    public void add(Brand brand) {
        SqlSession sqlSession = factory.openSession();

        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);

        // 调用方法
        mapper.add(brand);

        // 增删改的操作,需要事务的提交
        sqlSession.commit();

        sqlSession.close();
    }
}

dao 层(mapper 层)

public interface BrandMapper {
    /**
     * 查询 tb_brand 表中的所有数据
     * @return
     */
    @Select("select * from mybatis.tb_brand")
    @ResultMap("brandResultMap")
    List<Brand> selectAll();

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

sql 映射文件

<?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.luobin.mapper.BrandMapper">
    <!--遇到的部分的字段查询不到的时候,一般可能是数据库的名字与 pojo 里面属性的名字不一致导致的-->
    <!--这个时候需要使用 resultMap 进行名字的匹配即可-->
    <resultMap id="brandResultMap" type="brand">
        <result column="brand_name" property="brandName"></result>
        <result column="company" property="companyName"></result>
    </resultMap>

</mapper>

显示查询结果的 jsp

<%--
  Created by IntelliJ IDEA.
  User: yimeng
  Date: 2022/3/12
  Time: 6:16 下午
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--如果接收不到转发的数据,添加下面的代码 是因为 jsp 和 servlet 版本导致的默认关闭--%>
<%@page isELIgnored="false" %>
<!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">
                <tr>
                    <th>${brand.id}</th>
                    <th>${brand.brandName}</th>
                    <th>${brand.companyName}</th>
                    <th>${brand.ordered}</th>
                    <th>${brand.description}</th>
                    <th>${brand.status}</th>
                </tr>
            </c:forEach>

            <c:if test="${status == 1}">
                启用
            </c:if>
            <c:if test="${status != 1}">
                禁用
            </c:if>
        </table>

    </body>

    <%--点击新增加的页面,跳转到 jsp 页面,里面的表单中填写数据,发送到 Servlet 中--%>
    <script>
        document.getElementById("add").onclick = function () {
            location.href = "/brand-demo/addBrand.jsp"
        }
    </script>
</html>

进行表单上传的 jsp

<%--
  Created by IntelliJ IDEA.
  User: yimeng
  Date: 2022/3/13
  Time: 2:48 下午
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>添加品牌</title>
    </head>
    <body>
        <h3>添加品牌</h3>
        <form action="/brand-demo/AddServlet" 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>

8、会话技术(Cookie Session) 9、Filter(过滤器) 10、 Listener(监听器) 11、Ajax