我只想卷死各位,或者被各位卷死,在此特别感谢黑马程序员的JavaWeb教程
本文摘要:
理解 JSP 及 JSP 原理
能在 JSP中使用 EL表达式
和 JSTL标签
理解 MVC模式
和 三层架构
能完成品牌数据的增删改查功能
JSP概述
JSP(全称:Java Server Pages):Java 服务端页面。是一种动态的网页技术,其中既可以定义 HTML、JS、CSS等静态内容,还可以定义 Java代码的动态内容,也就是 JSP = HTML + Java
。如下就是jsp代码
1 2 3 4 5 6 7 8 9 10 11 <html> <head> <title>Title</title> </head> <body> <h1>hello jsp</h1> <% System.out.println("hello jsp" ); %> </body> </html>
上面代码 h1
标签内容是展示在页面上,而 Java 的输出语句是输出在 idea 的控制台。
JSP快速入门
搭建环境
创建一个maven的web项目
导入JSP依赖
在dependencies标签中导入JSP依赖
1 2 3 4 5 <dependency > <groupId > javax.servlet.jsp</groupId > <artifactId > jsp-api</artifactId > <scope > provided</scope > </dependency >
注意将该依赖的 scope
设置为 provided
,因为 tomcat 中有这个jar包了,所以在打包时我们是不希望将该依赖打进到我们工程的war包中。
创建JSP页面
在项目的 webapp
下创建一个名为hello.jsp的页面
编写代码
在 hello.jsp
页面中书写 HTML
标签和 Java
代码,如下
1 2 3 4 5 6 7 8 9 10 11 12 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>hello jsp</h1> <% System.out.println("HELLO JSP" ); %> </body> </html>
测试
启动服务器并访问该页面,我们可以在页面上看到一号标题的 hello jsp
,同时在IDEA的控制台可以看到输出的HELLO JSP
内容
JSP原理
之前说 JSP 就是一个页面,那么在 JSP 中写 html
标签,这很容易理解,但是为什么还可以写 Java
代码呢?
因为JSP 本质上就是一个 Servlet。下面我们来说说访问jsp时的流程
浏览器第一次访问 hello.jsp
页面,服务器会解析请求消息,找是否有index.jsp资源
如果有,tomcat
会将 hello.jsp
转换为名为 hello_jsp.java
的一个 Servlet
,但.java文件不能直接被访问
所以tomcat
再将转换的 Servlet
编译成字节码文件 hello_jsp.class
tomcat
会执行该字节码文件,向外提供服务
如果使用的是IDEA,那么可以在C:\Users\username\AppData\Local\JetBrains\IntelliJIdea2022.2\tomcat\虚拟路径\org\apache\jsp
目录下找到转换后的.java文件和.class文件
打开 hello_jsp.java
文件,来查看里面的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 package org.apache.jsp;import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.jsp.*;public final class hello_jsp extends org .apache.jasper.runtime.HttpJspBase implements org .apache.jasper.runtime.JspSourceDependent, org.apache.jasper.runtime.JspSourceImports { private static final javax.servlet.jsp.JspFactory _jspxFactory = javax.servlet.jsp.JspFactory.getDefaultFactory(); private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants; private static final java.util.Set<java.lang.String> _jspx_imports_packages; private static final java.util.Set<java.lang.String> _jspx_imports_classes; static { _jspx_imports_packages = new java .util.HashSet<>(); _jspx_imports_packages.add("javax.servlet" ); _jspx_imports_packages.add("javax.servlet.http" ); _jspx_imports_packages.add("javax.servlet.jsp" ); _jspx_imports_classes = null ; } private volatile javax.el.ExpressionFactory _el_expressionfactory; private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager; public java.util.Map<java.lang.String,java.lang.Long> getDependants() { return _jspx_dependants; } public java.util.Set<java.lang.String> getPackageImports() { return _jspx_imports_packages; } public java.util.Set<java.lang.String> getClassImports() { return _jspx_imports_classes; } public javax.el.ExpressionFactory _jsp_getExpressionFactory () { if (_el_expressionfactory == null ) { synchronized (this ) { if (_el_expressionfactory == null ) { _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); } } } return _el_expressionfactory; } public org.apache.tomcat.InstanceManager _jsp_getInstanceManager () { if (_jsp_instancemanager == null ) { synchronized (this ) { if (_jsp_instancemanager == null ) { _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig()); } } } return _jsp_instancemanager; } public void _jspInit () { } public void _jspDestroy () { } public void _jspService (final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response) throws java.io.IOException, javax.servlet.ServletException { final java.lang.String _jspx_method = request.getMethod();if (!"GET" .equals(_jspx_method) && !"POST" .equals(_jspx_method) && !"HEAD" .equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD" ); return ;} final javax.servlet.jsp.PageContext pageContext; javax.servlet.http.HttpSession session = null ; final javax.servlet.ServletContext application; final javax.servlet.ServletConfig config; javax.servlet.jsp.JspWriter out = null ; final java.lang.Object page = this ; javax.servlet.jsp.JspWriter _jspx_out = null ; javax.servlet.jsp.PageContext _jspx_page_context = null ; try { response.setContentType("text/html;charset=UTF-8" ); pageContext = _jspxFactory.getPageContext(this , request, response, null , true , 8192 , true ); _jspx_page_context = pageContext; application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); _jspx_out = out; out.write("\r\n" ); out.write("\r\n" ); out.write("<html>\r\n" ); out.write("<head>\r\n" ); out.write(" <title>Title</title>\r\n" ); out.write("</head>\r\n" ); out.write("<body>\r\n" ); out.write("<h1>hello jsp</h1>\r\n" ); System.out.println("hello jsp" ); out.write("\r\n" ); out.write("</body>\r\n" ); out.write("</html>\r\n" ); } catch (java.lang.Throwable t) { if (!(t instanceof javax.servlet.jsp.SkipPageException)){ out = _jspx_out; if (out != null && out.getBufferSize() != 0 ) try { if (response.isCommitted()) { out.flush(); } else { out.clearBuffer(); } } catch (java.io.IOException e) {} if (_jspx_page_context != null ) _jspx_page_context.handlePageException(t); else throw new ServletException (t); } } finally { _jspxFactory.releasePageContext(_jspx_page_context); } } }
第15行,hello_jsp类继承了HttpJspBase
这个类,通过查看HttpJspBase
类的继承关系,发现HttpJspBase
类继承了 HttpServlet
;那么 hello_jsp
这个类就间接的继承了 HttpServlet
,也就说明 hello_jsp
是一个 servlet
。
继续阅读 hello_jsp
类的代码,可以看到有一个名为 _jspService()
的方法,该方法就是每次访问 jsp
时自动执行的方法,和 servlet
中的 service
方法一样 。
而在 _jspService()
方法中可以看到往浏览器写标签的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 out.write("\r\n" ); out.write("\r\n" ); out.write("<html>\r\n" ); out.write("<head>\r\n" ); out.write(" <title>Title</title>\r\n" ); out.write("</head>\r\n" ); out.write("<body>\r\n" ); out.write("<h1>hello jsp</h1>\r\n" ); System.out.println("hello jsp" ); out.write("\r\n" ); out.write("</body>\r\n" ); out.write("</html>\r\n" );
以前我们自己写 servlet
时,这部分代码是由我们自己来写,现在有了 jsp
后,由tomcat完成这部分功能。
JSP脚本
SP脚本用于在 JSP页面内定义 Java代码。在之前的入门案例中我们就在 JSP 页面定义的 Java 代码就是 JSP 脚本。
JSP脚本分类
JSP 脚本有如下三个分类:
<%…%>:内容会直接放到_jspService()方法之中
<%=…%>:内容会放到out.print()中,作为out.print()的参数,此方法可以将Java代码中获取的数据动态的展示到页面中
<%!…%>:内容会放到_jspService()方法之外,被类直接包含
案例
需求
使用JSP脚本展示品牌数据
在该案例中数据不从数据库中查询,而是在 JSP 页面上写死
序号
品牌名称
企业名称
排序
品牌介绍
状态
</tr>
<tr align="center">
<td>1</td>
<td>三只松鼠</td>
<td>三只松鼠</td>
<td>100</td>
<td>三只松鼠,好吃不上火</td>
<td>启用</td>
</tr>
<tr align="center">
<td>2</td>
<td>优衣库</td>
<td>优衣库</td>
<td>10</td>
<td>优衣库,服适人生</td>
<td>禁用</td>
</tr>
<tr align="center">
<td>3</td>
<td>小米</td>
<td>小米科技有限公司</td>
<td>1000</td>
<td>为发烧而生</td>
<td>启用</td>
</tr>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 <table border="1" cellspacing="0" width="800" > <tr> <th>序号</th> <th>品牌名称</th> <th>企业名称</th> <th>排序</th> <th>品牌介绍</th> <th>状态</th> </tr> <tr align="center" > <td>1 </td> <td>三只松鼠</td> <td>三只松鼠</td> <td>100 </td> <td>三只松鼠,好吃不上火</td> <td>启用</td> </tr> <tr align="center" > <td>2 </td> <td>优衣库</td> <td>优衣库</td> <td>10 </td> <td>优衣库,服适人生</td> <td>禁用</td> </tr> <tr align="center" > <td>3 </td> <td>小米</td> <td>小米科技有限公司</td> <td>1000 </td> <td>为发烧而生</td> <td>启用</td> </tr> </table>
实现
在项目的 webapp
中创建 brand.jsp
,并将刚刚写死的页面中的内容拷贝过来。
在 brand.jsp
中准备一些数据,假装是从数据库来的数据
1 2 3 4 5 6 7 <% 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 )); %>
将 brand.jsp
页面中的 table
标签中的数据改为动态的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <table border="1" cellspacing="0" width="800" > <tr> <th>序号</th> <th>品牌名称</th> <th>企业名称</th> <th>排序</th> <th>品牌介绍</th> <th>状态</th> <% for (int i = 0 ; i < brands.size(); i++) { Brand brand = brands.get(i); %> </tr> <tr align="center" > <!--并将写死的属性值替换成brand的get方法,注意用 <%=%> 包裹起来--> <td><%=brand.getId()%></td> <td><%=brand.getBrandName()%></td> <td><%=brand.getCompanyName()%></td> <td><%=brand.getOrdered()%></td> <td><%=brand.getDescription()%></td> <td><%=brand.getStatus()==1 ?"启用" :"禁用" %></td> </tr> <% } %> </table>
成品代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 <%@ page import ="com.blog.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 <>(); 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> <hr> <table border="1" cellspacing="0" width="800" > <tr> <th>序号</th> <th>品牌名称</th> <th>企业名称</th> <th>排序</th> <th>品牌介绍</th> <th>状态</th> <th>操作</th> <% for (int i = 0 ; i < brands.size(); i++) { Brand brand = brands.get(i); %> </tr> <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()==1 ?"启用" :"禁用" %></td> <td><a href="#" >修改</a> <a href="#" >删除</a></td> </tr> <% } %> </table> </body> </html>
JSP缺点
通过上面的案例,我们可以看到 JSP 的很多缺点。
由于 JSP页面内,既可以定义 HTML 标签,又可以定义 Java代码,造成了以下问题:
书写麻烦:特别是复杂的页面,既要写 HTML 标签,还要写 Java 代码
阅读麻烦
复杂度高:运行需要依赖于各种环境,JRE,JSP容器,JavaEE…
占内存和磁盘:JSP会自动生成.java和.class文件占磁盘,运行的是.class文件占内存
调试困难:出错后,需要找到自动生成的.java文件进行调试
不利于团队协作:前端人员不会 Java,后端人员不精 HTML
如果页面布局发生变化,前端工程师对静态页面进行修改,然后再交给后端工程师,由后端工程师再将该页面改为 JSP 页面
基于上述的问题, JSP 已逐渐退出历史舞台,以后开发更多的是使用 HTML
+ Ajax
来替代。Ajax
是后续重点学习的技术。有个这个技术后,前端工程师负责前端页面开发,而后端工程师只负责前端代码开发。下来对技术的发展进行简单的说明
第一阶段:使用 servlet
即实现逻辑代码编写,也对页面进行拼接。这种模式我们之前也接触过
第二阶段:随着技术的发展,出现了 JSP
,人们发现 JSP
使用起来比 Servlet
方便很多,但是还是要在 JSP
中嵌套 Java
代码,也不利于后期的维护
第三阶段:使用 Servlet
进行逻辑代码开发,而使用 JSP
进行数据展示
第四阶段:使用 servlet
进行后端逻辑代码开发,而使用 HTML
进行数据展示。而这里面就存在问题,HTML
是静态页面,怎么进行动态数据展示呢?这就是 ajax
的作用了。
那既然 JSP 已经逐渐的退出历史舞台,那我们为什么还要学习 JSP
呢?原因有两点:
一些公司可能有些老项目还在用 JSP
,所以要求我们必须动 JSP
我们如果不经历这些复杂的过程,就不能体现后面阶段开发的简单
接下来我们来学习第三阶段,使用 EL表达式
和 JSTL
标签库替换 JSP
中的 Java
代码。
EL表达式
概述
EL(全称Expression Language )表达式语言,用于简化 JSP 页面内的 Java 代码。
EL 表达式的主要作用是 获取数据。其实就是从域对象中获取数据,然后将数据展示在页面上。
而 EL 表达式的语法也比较简单,${expression}
。例如:${brands}
就是获取域中存储的 key 为 brands 的数据。
代码演示
定义servlet,在 servlet 中封装一些数据并存储到 request 域对象中并转发到 el-demo.jsp
页面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @WebServlet("demo1") public class ServletDemo1 extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 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 )); request.setAttribute("brands" , brands); request.getRequestDispatcher("/el-demo.jsp" ).forward(request, response); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this .doGet(request, response); } }
注意:此处需要用转发,因为转发才可以使用 request 对象作为域对象进行数据共享
在 el-demo.jsp
中通过 EL表达式 获取数据
1 2 3 4 5 6 7 8 9 10 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <html> <head> <title>Title</title> </head> <body> ${brands} </body> </html>
可能遇到的问题:页面上只输出了${brands},而不是具体的数据
解决方案:在JSP页面头加上<%@ page isELIgnored="false" %>
在浏览器访问,得到以下数据
1 [Brand{id =1, brandName ='三只松鼠' , companyName ='三只松鼠' , ordered =100, description ='三只松鼠,好吃不上火' , status =1}, Brand{id =2, brandName ='优衣库' , companyName ='优衣库' , ordered =200, description ='优衣库,服适人生' , status =0}, Brand{id =3, brandName ='小米' , companyName ='小米科技有限公司' , ordered =1000, description ='为发烧而生' , status =1}]
域对象
JavaWeb中有四大域对象,分别是:
page:当前页面有效
request:当前请求有效
session:当前会话有效
application:当前应用有效
el 表达式获取数据,会依次从这4个域中寻找(域范围依次增大,层层包裹),直到找到为止。
例如: ${brands},el 表达式获取数据,会先从page域对象中获取数据,如果没有再到 requet 域对象中获取数据,如果再没有再到 session 域对象中获取,如果还没有才会到 application 中获取数据。
JSTL标签
概述
JSP标准标签库(Jsp Standarded Tag Library) ,使用标签取代JSP页面上的Java代码。如下代码就是JSTL标签
1 2 3 4 5 6 <c:if test="${flag == 1}" > 男 </c:if > <c:if test="${flag == 2}" > 女 </c:if >
上面代码看起来比 JSP 中嵌套 Java 代码看起来舒服好了。
这里只对两个最常用的标签进行讲解,<c:forEach>
标签和 <c:if>
标签。
JSTL 使用也是比较简单的,分为如下步骤:
导入坐标
1 2 3 4 5 6 7 8 9 10 <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标签库
1 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
使用标签
if标签
<c:if>
:相当于 if 判断
1 2 3 4 5 6 <c:if test="${flag == 1}" > 男 </c:if > <c:if test="${flag == 2}" > 女 </c:if >
代码演示:
定义一个 servlet
,在该 servlet
中向 request 域对象中添加 键是 status
,值为 1
的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 @WebServlet("/demo2") public class ServletDemo2 extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setAttribute("status" ,1 ); request.getRequestDispatcher("/jstl-if.jsp" ).forward(request,response); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this .doGet(request, response); } }
定义 jstl-if.jsp
页面,在该页面使用 <c:if>
标签
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>Title</title> </head> <body> <c:if test="${status == 1}" > 启用 </c:if > <c:if test="${status == 0}" > 禁用 </c:if > </body> </html>
注意要在该页面已经要引入 JSTL核心标签库<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
forEach标签
<c:forEach>
:相当于 for 循环。java中有增强for循环和普通for循环,JSTL 中的 <c:forEach>
也有两种用法
用法一
类似于 Java 中的增强for循环。涉及到的 <c:forEach>
中的属性如下
items:被遍历的容器
var:遍历产生的临时变量
varStatus:遍历状态对象
如下代码,是从域对象中获取名为 brands 数据,该数据是一个集合;遍历遍历,并给该集合中的每一个元素起名为 brand
,是 Brand对象。在循环里面使用 EL表达式获取每一个Brand对象的属性值
1 2 3 4 5 6 7 8 <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>
代码演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @WebServlet("/demo1") public class ServletDemo1 extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 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 )); request.setAttribute("brands" , brands); request.getRequestDispatcher("/jstl-foreach.jsp" ).forward(request, response); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this .doGet(request, response); } }
定义名为 jstl-foreach.jsp
页面,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <%@ 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> <hr> <table border="1" cellspacing="0" width="800" > <tr> <th>序号</th> <th>品牌名称</th> <th>企业名称</th> <th>排序</th> <th>品牌介绍</th> <th>状态</th> </tr> <c:forEach items="${brands}" var ="brand" > <tr align="center" > <td>${brand.id}</td> <td>${brand.brandName}</td> <td>${brand.companyName}</td> <td>${brand.ordered}</td> <td>${brand.description}</td> <td>${brand.status == 1 ? "启用" : "禁用" }</td> </tr> </c:forEach> </table> </body> </html>
这里的${brand.id}
,并不是直接获取的属性的id,而是调用的brand的getId()方法,底层实现是先将首字母大写,由id
变成Id
,然后在前面拼接一个get,从而变成getId
,随后调用brand的getId()
用法二
类似于 Java 中的普通for循环。涉及到的 <c:forEach>
中的属性如下
begin:开始数
end:结束数
step:步长
实例代码:
从0循环到10,变量名是 i
,每次自增1
1 2 3 <c:forEach begin="0" end="10" step="1" var ="i" > ${i} </c:forEach>
MVC格式与三层架构
MVC 模式和三层架构是一些理论的知识,将来我们使用了它们进行代码开发会让我们代码维护性和扩展性更好。
MVC模式
MVC 是一种分层开发的模式,其中:
M:Model,业务模型,处理业务
V:View,视图,界面展示
C:Controller,控制器,处理请求,调用模型和视图
控制器(serlvlet)用来接收浏览器发送过来的请求,控制器调用模型(JavaBean)来获取数据,比如从数据库查询数据;控制器获取到数据后再交由视图(JSP)进行数据展示。
MVC 好处:
三层架构
三层架构是将我们的项目分成了三个层面,分别是 表现层
、业务逻辑层
、数据访问层
。
数据访问层:对数据库的CRUD基本操作
业务逻辑层:对业务逻辑进行封装,组合数据访问层层中基本功能,形成复杂的业务逻辑功能。例如 注册业务功能
,我们会先调用 数据访问层
的 selectByName()
方法判断该用户名是否存在,如果不存在再调用 数据访问层
的 insert()
方法进行数据的添加操作
表现层:接收请求,封装数据,调用业务逻辑层,响应数据
而整个流程是,浏览器发送请求,表现层的Servlet接收请求并调用业务逻辑层的方法进行业务逻辑处理,而业务逻辑层方法调用数据访问层方法进行数据的操作,依次返回到serlvet,然后servlet将数据交由 JSP 进行展示。
MVC格式和三层架构
通过 MVC 和 三层架构 有什么区别和联系?
如上图上半部分是 MVC 模式,上图下半部分是三层架构。 MVC 模式
中的 C(控制器)和 V(视图)就是 三层架构
中的表现层,而 MVC 模式
中的 M(模型)就是 三层架构
中的 业务逻辑层 和 数据访问层。
可以将 MVC 模式
理解成是一个大的概念,而 三层架构
是对 MVC 模式
实现架构的思想。 那么我们以后按照要求将不同层的代码写在不同的包下,每一层里功能职责做到单一,将来如果将表现层的技术换掉,而业务逻辑层和数据访问层的代码不需要发生变化。
案例
需求:完成品牌数据的增删改查操作
这个案例是将今天学习的所有的内容(包含 MVC模式 和 三层架构)进行应用,并将整个流程贯穿起来
环境准备
环境准备工作,我们分以下步骤实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 <?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-demo</artifactId > <version > 1.0-SNAPSHOT</version > <packaging > war</packaging > <properties > <maven.compiler.source > 8</maven.compiler.source > <maven.compiler.target > 8</maven.compiler.target > </properties > <dependencies > <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis</artifactId > <version > 3.5.5</version > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 5.1.34</version > </dependency > <dependency > <groupId > javax.servlet</groupId > <artifactId > javax.servlet-api</artifactId > <version > 3.1.0</version > <scope > provided</scope > </dependency > <dependency > <groupId > javax.servlet.jsp</groupId > <artifactId > jsp-api</artifactId > <version > 2.2</version > <scope > provided</scope > </dependency > <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 >
创建三层架构的包结构
分别创建mapper
,pojo
,service
,util
,web
五个包
数据库表 tb_brand
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 CREATE DATABASE db1;USE db1; CREATE TABLE tb_brand( id INT PRIMARY KEY AUTO_INCREMENT, brand_name VARCHAR (20 ), company_name VARCHAR (20 ), ordered INT , description VARCHAR (100 ), 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;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 package com.blog.pojo;public class Brand { private Integer id; private String brandName; private String companyName; private Integer ordered; private String description; private Integer status; public Brand () { } 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 基础环境
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <configuration > <typeAliases > <package name ="com.blog.pojo" > </package > </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://localhost:13306/db1?useSSL=false& useServerPrepStmts=true" /> <property name ="username" value ="root" /> <property name ="password" value ="PASSWORD." /> </dataSource > </environment > </environments > <mappers > <package name ="com.blog.mapper" /> </mappers > </configuration >
BrandMapper.xml
由于数据库中的命名和Brand类的命名不一致,所以这里要用resultMap来解决
1 2 3 4 5 6 7 8 9 10 11 <?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.blog.mapper.BrandMapper" > <resultMap id ="brandResultMap" type ="brand" > <result column ="brand_name" property ="brandName" > </result > <result column ="company_name" property ="companyName" > </result > </resultMap > </mapper >
1 2 3 4 package com.blog.mapper;public interface BrandMapper {}
查询所有
当我们点击 index.html
页面中的 查询所有
这个超链接时,就能查询到产品的数据。
对于上述的功能,点击 查询所有
超链接是需要先请后端的 servlet
,由 servlet
跳转到对应的页面进行数据的动态展示。
编写index.html页面
1 2 3 4 5 6 7 8 9 10 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > </head > <body > <a href ="/brand_demo/selectAllServlet" > 查询所有</a > </body > </html >
编写BrandMapper
在 mapper
包下创建创建 BrandMapper
接口,在接口中定义 selectAll()
方法
1 2 3 @Select("select * from tb_brand") @ResultMap("brandResultMap") List<Brand> selectAll () ;
编写工具类
这个工具类的编写在上篇文章讲过
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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
1 2 3 4 5 6 7 8 9 10 11 public class BrandService { SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory(); public List<Brand> selectAll () { SqlSession sqlSession = sqlSessionFactory.openSession(); BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); List<Brand> brands = brandMapper.selectAll(); sqlSession.close(); return brands; } }
编写Servlet
在 web
包下创建名为 SelectAllServlet
的 servlet
,该 servlet
的逻辑如下:
调用 BrandService
的 selectAll()
方法进行业务逻辑处理,并接收返回的结果
将上一步返回的结果存储到 request
域对象中
跳转到 brand.jsp
页面进行数据的展示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @WebServlet("/selectAllServlet") public class SelectAllServlet extends HttpServlet { private BrandService brandService = new BrandService (); @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<Brand> brands = brandService.selectAll(); request.setAttribute("brands" , brands); request.getRequestDispatcher("/brand.jsp" ).forward(request, response); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this .doGet(request, response); } }
编写brand.jsp页面
在表格中使用 JSTL
和 EL表达式
从request域对象中获取名为 brands
的集合数据并展示出来。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <%@ 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> <hr> <table border="1" cellspacing="0" width="1200" > <tr> <th>序号</th> <th>品牌名称</th> <th>企业名称</th> <th>排序</th> <th>品牌介绍</th> <th>状态</th> <th>操作</th> </tr> <c:forEach items="${brands}" var ="brand" > <tr align="center" > <td>${brand.id}</td> <td>${brand.brandName}</td> <td>${brand.companyName}</td> <td>${brand.ordered}</td> <td>${brand.description}</td> <td>${brand.status == 1 ? "启用" : "禁用" }</td> <td><a href="/brand-demo/selectByIdServlet?id=${brand.id}" >修改</a> <a href="#" >删除</a></td> </tr> </c:forEach> </table> </body> </html>
测试
启动服务器,并在浏览器输入 http://localhost:8080/brand-demo/index.html
,看到如下 查询所有
的超链接,点击该链接就可以查询出所有的品牌数据
添加
编写BrandMapper方法
在 BrandMapper
接口,在接口中定义 add(Brand brand)
方法
1 2 @Insert("insert into tb_brand values(null,#{brandName},#{companyName},#{ordered},#{description},#{status})") void add (Brand brand) ;
编写BrandService方法
在 BrandService
类中定义添加品牌数据方法 add(Brand brand)
1 2 3 4 5 6 7 public void add (Brand brand) { SqlSession sqlSession = sqlSessionFactory.openSession(); BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); brandMapper.add(brand); sqlSession.commit(); sqlSession.close(); }
改进brand.jsp页面
在该页面表格的上面添加 新增
按钮
1 <input type ="button" value ="新增" id ="add" > <br >
并给该按钮绑定单击事件,当点击了该按钮需要跳转到 brand.jsp
添加品牌数据的页面
1 2 3 4 5 <script > document .getElementById ("add" ).onclick = function ( ){ location.href = "/brand_demo/addBrand.jsp" ; } </script >
编写addBrand.jsp页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <%@ 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_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>
编写servlet
在 web
包下创建 AddServlet
的 servlet
,该 servlet
的逻辑如下:
设置处理post请求乱码的字符集
接收客户端提交的数据
将接收到的数据封装到 Brand
对象中
调用 BrandService
的add()
方法进行添加的业务逻辑处理
跳转到 selectAllServlet
资源重新查询数据
具体的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 @WebServlet("/addServlet") public class AddServlet extends HttpServlet { private BrandService brandService = new BrandService (); @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8" ); String brandName = request.getParameter("brandName" ); String companyName = request.getParameter("companyName" ); Integer ordered = Integer.valueOf(request.getParameter("ordered" )); String description = request.getParameter("description" ); Integer status = Integer.valueOf(request.getParameter("status" )); Brand brand = new Brand (); brand.setOrdered(ordered); brand.setStatus(status); brand.setBrandName(brandName); brand.setCompanyName(companyName); brand.setDescription(description); brandService.add(brand); request.getRequestDispatcher("/selectAllServlet" ).forward(request, response); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this .doGet(request, response); } }
测试
点击 brand.jsp
页面的 新增
按钮,会跳转到 addBrand.jsp
页面,输入数据点击提交,可以看到刚添加的数据
修改
修改
功能需要从两方面进行实现,数据回显和修改操作。当我们点击修改时,页面上会显示原有的数据,而不是空白的,我们可以选择我们需要的来修改。
回显数据
######## 编写BrandMapper方法
在 BrandMapper
接口,在接口中定义 selectById(int id)
方法
1 2 3 @Select("select * from tb_brand where id = #{id}") @ResultMap("brandResultMap") Brand selectById (int id) ;
######## 编写BrandService方法
在 BrandService
类中定义根据id查询数据方法 selectById(int id)
1 2 3 4 5 6 7 public Brand selectById (int id) { SqlSession sqlSession = sqlSessionFactory.openSession(); BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); Brand brand = brandMapper.selectById(id); sqlSession.close(); return brand; }
######## 编写servlet
在 web
包下创建 SelectByIdServlet
的 servlet
,该 servlet
的逻辑如下:
获取请求数据 id
调用 BrandService
的 selectById()
方法进行数据查询的业务逻辑
将查询到的数据存储到 request 域对象中
跳转到 update.jsp
页面进行数据真实
具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @WebServlet("/selectByIdServlet") public class SelectByIdServlet extends HttpServlet { private BrandService brandService = new BrandService (); @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int id = Integer.parseInt(request.getParameter("id" )); Brand brand = brandService.selectById(id); request.setAttribute("brand" ,brand); request.getRequestDispatcher("/update.jsp" ).forward(request,response); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this .doGet(request, response); } }
######## 编写update.jsp页面
拷贝 addBrand.jsp
页面,改名为 update.jsp
并做出以下修改:
title
标签内容改为 修改品牌
form
标签的 action
属性值改为 /brand_demo/updateServlet
input
标签要进行数据回显,需要设置 value
属性1 2 3 品牌名称:<input name="brandName" value="${brand.brandName}" ><br> 企业名称:<input name="companyName" value="${brand.companyName}" ><br> 排序:<input name="ordered" value="${brand.ordered}" ><br>
textarea
标签要进行数据回显,需要在标签体中使用 EL表达式
1 描述信息:<textarea rows="5" cols="20" name="description" >${brand.description} </textarea><br>
单选框使用 if
标签需要判断 brand.status
的值是 1 还是 0 在指定的单选框上使用 checked
属性,表示被选中状态1 2 3 4 5 6 7 8 9 10 状态: <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 >
综上,update.jsp
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <%@ 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_demo/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="${brand.status == 1}" > <input type="radio" name="status" value="1" checked>启用 <input type="radio" name="status" value="0" >禁用 </c:if > <c:if test="${brand.status == 0}" > <input type="radio" name="status" value="1" >启用 <input type="radio" name="status" value="0" checked>禁用 </c:if > <input type="submit" value="提交" > </form> </body> </html>
修改数据
在修改页面进行数据修改,点击 提交
按钮,会将数据提交到后端程序,后端程序会对表中的数据进行修改操作,然后重新进行数据的查询操作。整体流程如下:
######## 编写BrandMapper方法
在 BrandMapper
接口,在接口中定义 update(Brand brand)
方法
1 2 3 @Update("update tb_brand set brand_name = #{brandName},company_name = #{companyName},ordered = #{ordered},description = #{description},status = #{status} where id = #{id}") @ResultMap("brandResultMap") void update (Brand brand) ;
######## 编写BrandService方法
在 BrandService
类中定义根据id查询数据方法 update(Brand brand)
1 2 3 4 5 6 7 public void update (Brand brand) { SqlSession sqlSession = sqlSessionFactory.openSession(); BrandMapper mapper = sqlSession.getMapper(BrandMapper.class); mapper.update(brand); sqlSession.commit(); sqlSession.close(); }
######## 编写servlet
在 web
包下创建 AddServlet
的 servlet
,该 servlet
的逻辑如下:
设置处理post请求乱码的字符集
接收客户端提交的数据
将接收到的数据封装到 Brand
对象中
调用 BrandService
的update()
方法进行添加的业务逻辑处理
跳转到 selectAllServlet
资源重新查询数据
具体的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 @WebServlet("/updateServlet") public class UpdateServlet extends HttpServlet { private BrandService brandService = new BrandService (); @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8" ); 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 = 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)); brandService.update(brand); 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提交到后端。
我们可以使用隐藏域解决这个问题
1 2 <%--隐藏域,提交id--%> <input type="hidden" name="id" value="${brand.id}" >
最终的update.jsp代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <%@ 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_demo/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 == 1}" > <input type="radio" name="status" value="1" checked>启用 <input type="radio" name="status" value="0" >禁用 </c:if > <c:if test="${brand.status == 0}" > <input type="radio" name="status" value="1" >启用 <input type="radio" name="status" value="0" checked>禁用 </c:if > <input type="submit" value="提交" > </form> </body> </html>
测试
访问页面,当我们点击修改时,数据会回显,修改完我们需要的之后,自动返回查询所有页面
删除
经过上面的学习,删除操作对我们来说已经非常简单了
修改brand.jsp
设置一下删除的超链接
1 <a href ="/brand_demo/deleteServlet?id=${brand.id}" > 删除</a > </td >
编写BrandMapper方法
在 BrandService
类中定义根据id查询数据方法 deleteById(int id)
1 2 3 @Delete("delete from tb_brand where id = #{id}") @ResultMap("brandResultMap") void deleteById (int id) ;
编写BrandService方法
在 BrandService
类中定义根据id查询数据方法 selectById(int id)
1 2 3 4 5 6 7 public void deleteById (int id) { SqlSession sqlSession = sqlSessionFactory.openSession(); BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); brandMapper.deleteById(id); sqlSession.commit(); sqlSession.close(); }
编写servlet
在 web
包下创建 SelectByIdServlet
的 servlet
,该 servlet
的逻辑如下:
获取请求数据 id
调用 BrandService
的 deleteById()
方法进行数据查询的业务逻辑
跳转到 selectAllServlet
资源重新查询数据
具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @WebServlet("/deleteServlet") public class DeleteServlet extends HttpServlet { private BrandService brandService = new BrandService (); @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int id = Integer.parseInt(request.getParameter("id" )); brandService.deleteById(id); request.getRequestDispatcher("/selectAllServlet" ).forward(request, response); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this .doGet(request, response); } }
测试
访问页面,点击删除,页面自动刷新,数据已被删除