JSP、EL表达式、JSTL标签、MVC模式和三层架构

目录

JSP快速入门

JSP原理

JSP脚本

EL表达式

JSTL标签

MVC模式和三层架构

案例


JSP(全称:Java Server Pages):Java 服务端页面。
是一种动态的网页技术,其中既可以定义 HTML、JS、CSS等静态内容 
JSP  =  HTML  +  Java
<html>
    <head>
        <title>Title</title>
    </head>
    <body>
        <h1>JSP,Hello World</h1>
        <%
            System.out.println("hello,jsp~");
        %>
    </body>
</html>

上面代码 h1 标签内容是展示在页面上,而 Java 的输出语句是输出在 idea 的控制台。
JSP 作用:简化开发,避免了在Servlet中直接输出HTML标签。

JSP快速入门

导入 JSP 依赖

<!--jsp 依赖-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>
该依赖的 scope 必须设置为 provided ,因为 tomcat 中有这个jar包了,
所以在打包时是不希望将该依赖打进工程的war包中。

 创建 jsp 页面

 编写代码

<%@page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
    <body>
        <h1>JSP,Hello World</h1>
        <%
             System.out.println("hello,jsp~");
        %>
    </body>
</html>

测试

启动服务器并在浏览器地址栏输入 http://localhost:8080/jsp-demo/hello.jsp
在浏览器和idea的控制台看到输出的 hello,jsp~ 内容。
JSP 本质上就是一个 Servlet

 

JSP原理

1. 浏览器第一次访问 hello.jsp 页面
2. tomcat 会将 hello.jsp 转换为名为 hello_jsp.java 的一个 Servlet
3. tomcat 再将转换的 servlet 编译成字节码文件 hello_jsp.class
4. tomcat 会执行该字节码文件,向外提供服务

JSP脚本

JSP 脚本有如下三个分类:
    <%...%>:内容会直接放到_jspService()方法之中
    <%=.%>:内容会放到out.print()中,作为out.print()的参数
    <%!.%>:内容会放到_jspService()方法之外,被类直接包含
<%
    System.out.println("hello,jsp~"); 
    int i = 3;
%>
通过浏览器访问 hello.jsp 后,查看转换的 hello_jsp.java 文件,
i 变量定义在了 _jspService() 方法中

 

<%="hello"%>
<%=i%>

 

<%!
void   show(){}
String name = "zhangsan";
%>

 

案例
需求
使用JSP脚本展示品牌数据

 

<%@ page import="com.green.pojo.Brand" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ 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>

        <%
            if (brand.getStatus() == 1) {
                //显示启用
        %>
        <td><%="启用"%>
        </td>
        <%
        } else {
            //显示禁用
        %>
        <td><%="禁用"%>
        </td>
        <%
            }
        %>

        <td><a href="#">修改</a> <a href="#">删除</a></td>
    </tr>

    <%
        }
    %>

</table>

</body>
</html>
JSP 缺点
书写麻烦:特别是复杂的页面
既要写 HTML 标签,还要写 Java 代码阅读麻烦
代码需要花费很长的时间去梳理
复杂度高:运行需要依赖于各种环境,JRE,JSP容器,JavaEE.
占内存和磁盘:JSP会自动生成.java和.class文件占磁盘,运行的是.class文件占内存
调试困难:出错后,需要找到自动生成的.java文件进行调试
不利于团队协作:前端人员不会 Java,后端人员不精 HTML
如果页面布局发生变化,前端工程师对静态页面进行修改,然后再交给后端工程师,
由后端工程师再将该页面改为 JSP页面

 JSP 已逐渐退出历史舞台,以后开发更多的是使用 HTML + Ajax 来替代

 

EL表达式

概述
EL(全称Expression Language )表达式语言,用于简化 JSP 页面内的 Java 代码。
EL 表达式的主要作用是 获取数据。其实就是从域对象中获取数据,然后将数据展示在页面上。
而 EL 表达式的语法也比较简单,${expression} 。
例如:${brands} 就是获取域中存储的 key 为 brands 的数据。

代码演示 

定义servlet,在servlet中封装一些数据并存储到request域对象中并转发到el-demo.jsp 页面。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<%--el表达式--%>
${brands}

</body>
</html>
package com.green.web;

import com.green.pojo.Brand;

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

@WebServlet("/demo1")
public class ServletDemo1 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
        request.getRequestDispatcher("/el-demo.jsp").forward(request, response);
    }

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

 域对象

JavaWeb中有四大域对象,分别是:
page:当前页面有效
request:当前请求有效
session:当前会话有效
application:当前应用有效
el 表达式获取数据,会依次从这4个域中寻找,直到找到为止。而这四个域对象的作用范围如下图所示
例如: ${brands},el 表达式获取数据,会先从page域对象中获取数据,
如果没有再到 requet 域对象中获取数据,如果再没有再到 session 域对象中获取,
如果还没有才会到 application 中获取数据。

JSTL标签

JSP标准标签库(Jsp Standarded Tag Library) ,使用标签取代JSP页面上的Java代码。

 导入坐标

<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>

JSP页面上引入JSTL标签库 

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

使用标签 

if 标签
<c:if> :相当于 if 判断
属性:test,用于定义条件表达式
<c:if test="${status == 1}">
    启用
</c:if>
<c:if test="${status == 0}">
    禁用
</c:if>
代码演示:
定义一个servlet ,在该servlet中向request域对象中添加键是status ,值为 1 的数据
@WebServlet("/demo2")
public class ServletDemo2 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 存储数据到request域中
        request.setAttribute("status", 1);

//2. 转发到 jstl-if.jsp
        request.getRequestDispatcher("/jstl-if.jsp").forward(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--
c:if:来完成逻辑判断,替换java   if else
--%>
<c:if test="${status == 1}">
    启用
</c:if>
<c:if test="${status == 0}">
    禁用
</c:if>

</body>
</html>
forEach 标签
<c:forEach> :相当于 for 循环。java中有增强for循环和普通for循环,
JSTL 中的 <c:forEach> 也有两种用法
用法一
类似于 Java 中的增强for循环。涉及到的 <c:forEach> 中的属性如下
items:被遍历的容器
var:遍历产生的临时变量
varStatus:遍历状态对象
如下代码,是从域对象中获取名为 brands 数据,该数据是一个集合;
遍历,并给该集合中的每一个元素起名为brand ,是 Brand对象。
在循环里面使用 EL表达式获取每一个Brand对象的属性值
<c:forEach items="${brands}" var="brand">
    <tr align="center">
        <td>${brand.id}</td>
        <td>${brand.brandName}</td>
        <td>${brand.companyName}</td>
        <td>${brand.description}</td>
    </tr>
</c:forEach>
代码演示:
servlet 还是使用之前的名为 ServletDemo1 。
定义名为 jstl-foreach.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</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>

    <c:forEach items="${brands}" var="brand" varStatus="status">

        <tr align="center">
                <%--            <td>${brand.id}</td>--%>
                <%--
                index:从0开始
                count:从1开始
                --%>
            <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 == 0}">
                <td>禁用</td>
            </c:if>
                <%--            <td>${brand.status}</td>--%>
            <td><a href="#">修改</a> <a href="#">删除</a></td>
        </tr>

    </c:forEach>

</table>

<hr>
<c:forEach begin="1" end="10" step="1" var="i">
    <a href="#">${i}</a>
</c:forEach>
</body>
</html>
用法二
类似于Java中的普通for循环。涉及到的 <c:forEach> 中的属性如下
begin:开始数
end:结束数
step:步长
实例代码:
从0循环到10,变量名是 i ,每次自增1
<c:forEach begin="10" end="10" step="1" var="i">
    ${i}
</c:forEach>

MVC模式和三层架构

MVC 是一种分层开发的模式,其中:
M:Model,业务模型,处理业务
V:View,视图,界面展示
C:Controller,控制器,处理请求,调用模型和视图

 

控制器(serlvlet)用来接收浏览器发送过来的请求,控制器调用模型(JavaBean)来获取数据,
比如从数据库查询数据;控制器获取到数据后再交由视图(JSP)进行数据展示。
MVC 好处:
职责单一,互不影响。每个角色做它自己的事,各司其职。
有利于分工协作。
有利于组件重用

 三层架构

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

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

三层架构的每一层都有特有的包名称:
表现层: com.test.controller 或者 com.test.web
业务逻辑层: com.test.service
数据访问层: com.test.dao 或者 com.test.mapper

 

 

如上图上半部分是 MVC 模式,上图下半部分是三层架构。
MVC 模式中的c(控制器)和V(视图)就是三层架构中的表现层,
而MVC模式中的M(模型)就是三层架构中的业务逻辑层和数据访问层。
可以将 MVC  模式 理解成是一个大的概念,而三层架构是对MVC模式实现架构的思想。 
那么以后按照要求将不同层的代码写在不同的包下,每一层里功能职责做到单一,
将来如果将表现层的技术换掉,而业务逻辑层和数据访问层的代码不需要发生变化。

案例

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

环境准备
创建新的模块 brand_demo,引入坐标
创建三层架构的包结构
数据库表 tb_brand
实体类 Brand 
MyBatis 基础环境
    Mybatis-config.xml 
    BrandMapper.xml 
    BrandMapper接口
创建工程
创建新的模块 brand_demo,引入坐标
mysql的驱动包
要使用mybatis框架。
mybaits的依赖包
web项目需要用到servlet和jsp。
servlet和jsp的依赖包
需要使用 jstl 进行数据展示。jstl的依赖包
<?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>brand-deno</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <maven.compiler.source>13</maven.compiler.source>
        <maven.compiler.target>13</maven.compiler.target>
    </properties>

    <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.46</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>

</project>
创建包
创建不同的包结构,用来存储不同的类。包结构如下

 

 查询所有

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

 

编写BrandMapper
在 mapper 包下创建创建 BrandMapper 接口,在接口中定义 selectAll() 方法
/**
* 查询所有
* @return
*/
@Select("select * from tb_brand")
@ResultMap("brandResultMap")
List<Brand> selectAll();
//编写工具类
//在utils包下创建名为 SqlSessionFactoryUtils 工具类
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;
    }
}
    public static SqlSessionFactory getSqlSessionFactory(){ 
        return sqlSessionFactory;
    }
}
//编写BrandService
//在 service 包下创建 BrandService 类
public class BrandService {
    //SqlSessionFactory初始化
    SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();
    /**
     * 查询所有
     * @return
     */
    //调用BrandMapper.selectAll()
    public List<Brand> selectAll(){
        //2、调用SqlSession
        SqlSession sqlSession = factory.openSession();
        //3、获取BrandMa
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        //4、调用方法
        List<Brand> brands = mapper.selectAll();
        sqlSession.close();
        return brands;
    }
}
/*
* 编写Servlet
在 web 包下创建名为 SelectAllServlet 的 servlet ,该 servlet 的逻辑如下:
调用 BrandService 的 selectAll() 方法进行业务逻辑处理,
并接收返回的结果将上一步返回的结果存储到 request 域对象中
跳转到 brand.jsp 页面进行数据的展示
* */
@WebServlet("/selectAllServlet")
public class SelectAllServlet extends HttpServlet {
    //创建BrandServlet对象
    private BrandService service = new BrandService();
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1、调用BrandServlet完成查询
        List<Brand> brands = service.selectAll();
        //2、存入request域中
        request.setAttribute("brands",brands);
        //3、转发到brand.jsp
        request.getRequestDispatcher("/brand.jsp").forward(request,response);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}
//编写brand.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</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>--%>
                <%--
                index:从0开始
                count:从1开始
                --%>
            <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 == 0}">
                <td>禁用</td>
            </c:if>
                <%--            <td>${brand.status}</td>--%>
            <td><a href="#">修改</a> <a href="#">删除</a></td>
        </tr>

    </c:forEach>

</table>

<script>
    document.getElementById("add").onclick = function () {
        location.href = "/brand-deno/addBrand.jsp"
    }
</script>
</body>
</html>
<!-- 查询到的字段名和实体类对象的属性名没有一一对应  起别名解决-->
<?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.green.mapper.BrandMapper">
    <!--  给字段起别名-->
    <resultMap id="brandResultMap" type="brand">
        <result column="brand_name" property="brandName"></result>
        <result column="company_name" property="companyName"></result>
    </resultMap>
</mapper>

 添加

点击新增按钮后,会先跳转到addBrand.jsp新增页面,在该页面输入要添加的数据,
输入完毕后点击 提交 按钮,需要将数据提交到后端,而后端进行数据添加操作,
并重新将所有的数据查询出来。

 

编写BrandMapper方法
在 BrandMapper 接口,在接口中定义 add(Brand  brand) 方法
/**
* 添加
* @param brand
*/
@Insert("insert into tb_brand values (null,#{brandName},#{companyName},#{ordered},#{description},#{status})")
    void add(Brand brand);
}
编写BrandService方法
在 BrandService 类中定义添加品牌数据方法 add(Brand  brand)
    /**
     * 添加
     * @param brand
     */
    public void add(Brand brand) {
        //2、调用SqlSession
        SqlSession sqlSession = factory.openSession();

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

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

        //提交事务
        sqlSession.commit();

        //释放资源
        sqlSession.close();
    }
}
编写addBrand.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">

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

    <input type="submit" value="提交">
</form>
</body>
</html>
编写servlet
在 web 包下创建 AddServlet 的 servlet ,该 servlet 的逻辑如下:
设置处理post请求乱码的字符集
接收客户端提交的数据
将接收到的数据封装到 Brand 对象中
调用 BrandService 的 add() 方法进行添加的业务逻辑处理
跳转到 selectAllServlet 资源重新查询数据

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

    //创建BrandServlet对象
    private BrandService service = new BrandService();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //处理post请求乱码问题
        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 brand = new Brand();
        brand.setBrandName(brandName);
        brand.setCompanyName(companyName);
        brand.setOrdered(Integer.parseInt(ordered));
        brand.setDescription(description);
        brand.setStatus(Integer.parseInt(status));

        //2、调用service完成添加
        service.add(brand);

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

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

 修改

回显数据

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

 

编写BrandMapper方法
在 BrandMapper 接口,在接口中定义 selectById(int id) 方法
    /**
     * 根据id查询数据
     * @param id
     * @return
     */
    @Select("select * from tb_brand where id = #{id}")
    @ResultMap("brandResultMap")
    Brand selectById(int id);
编写BrandService方法
在 BrandService 类中定义根据id查询数据方法 selectById(int id)
    /**
     * 根据id查询数据回显
     * @param id
     * @return
     */
    public Brand selectById(int id){

        //2、调用SqlSession
        SqlSession sqlSession = factory.openSession();

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

        //4、调用方法
        Brand brand = mapper.selectById(id);

        sqlSession.close();

        return brand;
    }
编写servlet
在 web 包下创建 SelectByIdServlet 的 servlet ,该 servlet 的逻辑如下:
获取请求数据 id
调用 BrandService 的 selectById() 方法进行数据查询的业务逻辑
将查询到的数据存储到 request 域对象中
跳转到 update.jsp 页面进行数据真实
@WebServlet("/selectByIdServlet")
public class SelectByIdServlet extends HttpServlet {

    //创建BrandServlet对象
    private BrandService service = new BrandService();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //接收id
        String id = request.getParameter("id");

        //1、调用service完成查询
        Brand brand = service.selectById(Integer.parseInt(id));

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

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

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}
编写update.jsp页面
input 标签要进行数据回显,需要设置 value 属性
<%@ 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-deno/updateServlet" 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="${status == 0}">
        <label><input type="radio" name="status" value="0" checked>禁用</label>
        <label><input type="radio" name="status" value="1">启用<br></label>
    </c:if>

    <c:if test="${status == 1}">
        <label><input type="radio" name="status" value="0">禁用</label>
        <label><input type="radio" name="status" value="1" checked>启用<br></label>
    </c:if>

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

 修改数据

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

 

编写BrandMapper方法
在 BrandMapper 接口,在接口中定义 update(Brand  brand) 方法
    /**
     * 根据id修改数据
     * @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);
编写BrandService方法
在 BrandService 类中定义根据id查询数据方法 update(Brand brand)
    /**
     * 根据id修改数据
     * @param brand
     */
    public void update(Brand brand) {
        //2、调用SqlSession
        SqlSession sqlSession = factory.openSession();

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

        //4、调用方法
        mapper.update(brand);

        //提交事务
        sqlSession.commit();

        //释放资源
        sqlSession.close();
    }
编写servlet
在 web 包下创建 AddServlet 的 servlet ,该 servlet 的逻辑如下:
设置处理post请求乱码的字符集
接收客户端提交的数据
将接收到的数据封装到 Brand 对象中
调用 BrandService 的 update() 方法进行添加的业务逻辑处理
跳转到 selectAllServlet 资源重新查询数据

@WebServlet("/updateServlet")
public class UpdateServlet extends HttpServlet {

    //创建BrandServlet对象
    private BrandService service = new BrandService();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //处理post请求乱码问题
        request.setCharacterEncoding("UTF-8");

        //1、接收表单数据,封装成一个Brand对象
        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");

        //封装成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));

        //2、调用service完成修改
        service.update(brand);

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

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

 存在问题:update.jsp 页面提交数据时是没有携带主键数据的,而后台修改数据需要根据主键进行修改

针对这个问题,我们不希望页面将主键id展示给用户看,但是又希望在提交数据时能将主键id提交到后端。
此时使用隐藏域,在 update.jsp 页面的表单中添加如下代码:
<%--隐藏域,提交id--%>
<input type="hidden" name="id" value="${brand.id}">
<%@ 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-deno/updateServlet" method="post">

    <%--隐藏域 提交id--%>
    <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}">
        <label><input type="radio" name="status" value="0" checked>禁用</label>
        <label><input type="radio" name="status" value="1">启用<br></label>
    </c:if>

    <c:if test="${brand.status == 1}">
        <label><input type="radio" name="status" value="0">禁用</label>
        <label><input type="radio" name="status" value="1" checked>启用<br></label>
    </c:if>

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

删除数据

编写BrandMapper方法
在 BrandMapper 接口,在接口中定义 deleteById(int id) 方法    
/**
     * 删除
     * @param id
     */
    @Delete("delete from tb_brand where id = #{id}")
    void deleteById(int id);
编写BrandService方法
在 BrandService 类中定义根据id删除数据方法 deleteById(int id)
  /**
     * 根据id删除数据
     * @param id
     */
    public void deleteById(int id) {
        //2、调用SqlSession
        SqlSession sqlSession = factory.openSession();

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

        //4、调用方法
        mapper.deleteById(id);//12

        //提交事务
        sqlSession.commit();

        //释放资源
        sqlSession.close();
    }
编写servlet
在 web 包下创建 DeleteByIdServlet 的 servlet ,该 servlet 的逻辑如下:
接收客户端提交的id
调用 BrandService 的 DeleteById(int id) 方法进行删除的业务逻辑处理
跳转到 selectAllServlet 资源重新查询数据
@WebServlet("/deleteByIdServlet")
public class DeleteByIdServlet extends HttpServlet {

    //创建BrandServlet对象
    private BrandService service = new BrandService();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //接收id
        String id = request.getParameter("id");

        //2、调用service完成删除
        service.deleteById(Integer.parseInt(id));

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

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}
brand.jsp 页面的删除连接
<a href="/brand-deno/deleteByIdServlet?id=${brand.id}">删除</a></td>

猜你喜欢

转载自blog.csdn.net/weixin_52270382/article/details/130107397
今日推荐