湘西北京网站建设,程序员是学什么专业,如何买域名发布网站,旅行网站建设论文摘要JSP 定义 JSP#xff08;Java Server Pages#xff09;#xff0c;即Java服务端页面。它是一种动态的网页技术#xff0c;其中可以定义HTML、CSS、JS等静态内容#xff0c;还可以定义Java代码的动态内容JSP HTML Java 说白了JSP就是一个页面#xff0c;它既可以写HTML标…JSP 定义 JSPJava Server Pages即Java服务端页面。它是一种动态的网页技术其中可以定义HTML、CSS、JS等静态内容还可以定义Java代码的动态内容JSP HTML Java 说白了JSP就是一个页面它既可以写HTML标签又可以写Java代码 简单示例 % page contentTypetext/html;charsetUTF-8 languagejava %
htmlheadtitleTitle/title/headbodyh1JSPHELLO WORLD!!!/h1%System.out.println(Hello JSP);%/body
/html其中html标签代码最终会被浏览器解析并显示在页面上而java代码会显示在服务器的控制台上运行截图如下 注意若利用Tomcat插件运行导致jsp文件无法在浏览器解析出现如图所示页面错误代表当前所用的JDK版本太高了 解决方式一用自己本地的Tomcat运行Web项目配置本地的Tomcat详见JavaWeb------Tomcat中的IDEA中使用Tomcat那一部分内容解决方式二将JDK版本降为1.8然后用Tomcat插件运行就不会出错了
JSP快速入门 步骤 Step1在pom.xml文件中导入JSP坐标依赖 JSP坐标需要设置坐标依赖范围为provided即该坐标在编译和测试时有效 因为Tomcat中已经提供好了JSP的jar包所以在打包后应该排除掉自己所设置的jar包若不排除则会报错 注意Servlet坐标依赖也是需要设置坐标依赖范围为provided原因与其相同
dependencygroupIdjavax.servlet.jsp/groupIdartifactIdjsp-api/artifactIdversion2.2/versionscopeprovided/scope
/dependency- 完整pom.xml文件如下xmlproject xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsdmodelVersion4.0.0/modelVersiongroupIdorg.example/groupIdartifactIdJspDemo/artifactIdpackagingwar/packagingversion1.0-SNAPSHOT/versionnameJspDemo Maven Webapp/nameurlhttp://maven.apache.org/urldependenciesdependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion3.8.1/versionscopetest/scope/dependency!--JSP坐标依赖 注意别忘了加上坐标依赖范围--dependencygroupIdjavax.servlet.jsp/groupIdartifactIdjsp-api/artifactIdversion2.2/versionscopeprovided/scope/dependency/dependenciesbuildfinalNameJspDemo/finalNameplugins!-- Tomcat插件 --plugingroupIdorg.apache.tomcat.maven/groupIdartifactIdtomcat7-maven-plugin/artifactIdversion2.2/version/plugin/plugins/build/projectStep2创建JSP文件 注意不能将JSP文件放到webapp目录下的WEB-INF目录下因为该目录不能通过浏览器直接访问到应该直接放到webapp目录下 Step3编写HTML标签和Java代码该步骤省略可详见JSP快速入门 Java代码被包裹在% 这中间写Java代码 %中间
JSP原理 JSP本质上就是一个Servlet。 JSP在被访问时由JSP容器即Tomcat将其转换为Java文件即Servlet然后在由JSP容器即Tomcat将其编译最终对外提供服务的其实就是这个字节码文件 详解如下 浏览器请求资源且第一次访问hello.jsp文件时JSP文件会被JSP容器即Tomcat转换为Servletjava文件这个过程是Tomcat自动完成的然后在由Tomcat自动进行编译最终向浏览器发出响应 JSP容器即Tomcat会自动将JSP文件解析为对应包含HTML代码和Java代码的Java文件提供服务的其实就是最后生成的字节码文件 JSP工作流程 编写 JSP 页面 开发者编写一个 JSP 页面包含 HTML 和嵌入的 Java 代码。编译 JSP 页面 JSP 容器将 JSP 页面编译成一个 Java servlet 类这个类继承自 HttpJspBase。 通过继承 HttpJspBaseJSP 页面的 servlet 能够有效地利用 servlet 的生命周期方法并且使 JSP 页面能够与 servlet 容器集成处理 HTTP 请求和响应。 初始化 在 servlet 被加载时容器调用 jspInit() 方法进行初始化。处理请求 每次请求到达时容器调用 servlet 的 service() 方法进而调用 _jspService() 方法来处理请求。销毁 当 servlet 被卸载时容器调用 jspDestroy() 方法进行清理。 示例以JSP快速入门的hello.jsp文件为例,hello.jsp代码如下 % page contentTypetext/html;charsetUTF-8 languagejava %
htmlheadtitleTitle/title/headbodyh1JSPHELLO WORLD!!!/h1%System.out.println(Hello JSP);%/body
/htmlStep1代开当前Web项目的目录 Step2打开当前项目目录下的target目录→tomcat→work→然后一直进入到jsp目录下 Step3会发现有一个java文件该文件就是JSP文件所生成的对应Java文件打开该hello_jsp.java文件代码如下 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.HttpJspBaseimplements org.apache.jasper.runtime.JspSourceDependent {private static final javax.servlet.jsp.JspFactory _jspxFactory javax.servlet.jsp.JspFactory.getDefaultFactory();private static java.util.Mapjava.lang.String,java.lang.Long _jspx_dependants;private javax.el.ExpressionFactory _el_expressionfactory;private org.apache.tomcat.InstanceManager _jsp_instancemanager;public java.util.Mapjava.lang.String,java.lang.Long getDependants() {return _jspx_dependants;}public void _jspInit() {_el_expressionfactory _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();_jsp_instancemanager org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());}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 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;charsetUTF-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( titleTitle/title\r\n);out.write( /head\r\n);out.write( body\r\n);out.write( h1JSPHELLO WORLD!!!/h1\r\n);out.write( );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 { 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);}}
}在该代码中我们发现Tomcat将jsp文件代码以java代码的形式写了出来 Tomcat将JSP文件转换为Java文件后该文件extends org.apache.jasper.runtime.HttpJspBaseHttpJspBase类继承自 HttpServlet所以该Java文件属于Servlet类 对HttpJspBase类详解 初始化和清理 HttpJspBase 提供了 jspInit() 和 jspDestroy() 方法分别对应 servlet 的 init() 和 destroy() 方法。这些方法允许 JSP 页面在初始化和销毁时执行特定的代码。服务方法 HttpJspBase 类会覆盖 service() 方法以便调用 _jspService(HttpServletRequest request, HttpServletResponse response) 方法这是每个 JSP 页面必须实现的一个方法用于处理请求和生成响应。编译过程 当 JSP 页面被容器如 Apache Tomcat编译时它会生成一个继承自 HttpJspBase 的 servlet 类。生成的 servlet 类会实现 _jspService() 方法该方法包含了 JSP 页面中的实际代码。
JSP脚本 作用用于在JSP页面内定义Java代码 JSP脚本分类 分类解释%...%内容会直接放到_jspService()方法之中%...%内容会放到out.print()之中作为out.print()的参数%!...%内容会直接放到_jspService()方法之外被类继续包含。即跟属性、方法属于同一级 示例 % page contentTypetext/html;charsetUTF-8 languagejava %
htmlheadtitleTitle/title/headbodyh1JSPHELLO WORLD!!!/h1!--第一种脚本--%System.out.println(Hello JSP);int i 3;%!--第二种脚本--%i为 3%!--第三种脚本--%!void show(){}String name zhangsan;%/body
/html第一种脚本%...%会在生成的java文件的_jspService()方法之中如下代码所示(注意博主把该_jspService方法内的无关代码均已删除这样能清楚看出来该脚本内的代码在该方法之中)html代码也在_jspService()方法之中 如下代码所示 public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)throws java.io.IOException, javax.servlet.ServletException {try {out.write(\r\n);out.write(\r\n);out.write(html\r\n);out.write( head\r\n);out.write( titleTitle/title\r\n);out.write( /head\r\n);out.write( body\r\n);out.write( h1JSPHELLO WORLD!!!/h1\r\n);out.write( !--第一种脚本--\r\n);out.write( );System.out.println(Hello JSP);int i 3;out.write(\r\n);out.write( !--第二种脚本--\r\n);out.write( );out.print(i为 i);out.write(\r\n);out.write( !--第三种脚本--\r\n);out.write( );out.write(\r\n);out.write( /body\r\n);out.write(/html\r\n);} }第二种脚本%...%也会在生成的java文件的_jspService()方法之中不过它的内容会放到out.print()之中作为out.print()的参数最终输出到页面上代码详见第一种脚本处的代码Tomcat运行该Web项目后页面显示如下 第三种脚本%!...%内容会直接放到_jspService()方法之外被类继续包含。即跟属性、方法属于同一级如下所示注意代码均为省略形式以便明了 public final class hello_jsp extends org.apache.jasper.runtime.HttpJspBaseimplements org.apache.jasper.runtime.JspSourceDependent {void show(){}String name zhangsan;
}JSP脚本示例 将数据库中的商品显示在浏览器页面 brand对象类 package at.guigu.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, 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;}Overridepublic String toString() {return Brand{ id id , brandName brandName \ , companyName companyName \ , ordered ordered , description description \ , status status };}
}brand.jsp文件 % page importat.guigu.pojo.Brand %
% page importjava.util.ArrayList %
% page importjava.util.List %
% page contentTypetext/html;charsetUTF-8 languagejava %%//模拟查询数据库ListBrand 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 langenheadmeta charsetUTF-8titleTitle/title/headbodyinput typebutton value新增brhrtable border1 cellspacing0 width800trth序号/thth品牌名称/thth企业名称/thth排序/thth品牌介绍/thth状态/thth操作/th/tr%for (int i 0; i brands.size(); i) {Brand brand brands.get(i);//获取第i个对象%tr aligncentertd%brand.getId()%/tdtd%brand.getBrandName()%/tdtd%brand.getCompanyName()%/tdtd%brand.getOrdered()%/tdtd%brand.getDescription()%/tdtd%if (brand.getStatus() 0) {%%禁用%%}else {%%启用%%}%/tdtda href#修改/a a href#删除/a/td/tr%}%/table/body
/html注意以下这一部分代码可改为 td%if (brand.getStatus() 0) {%%禁用%%}else {%%启用%%}%
/td
!--等同于--
%if (brand.getStatus() 0) {
%td%禁用%/td
%}else {
%td%启用%/td
%}
%Tomcat运行该Web项目后页面运行截图如下 注意事项 在JSP文件中Java代码可跟Html代码可嵌套来写但是Java代码要写在JSP脚本中Html代码不能写在脚本中如下所示 嵌套方式来写java和html代码比较麻烦对于复杂的页面不利于阅读和调试等工作所以最好不要在JSP中直接写Java代码 %if (brand.getStatus() 0) {
%td%禁用%/td
%}else {
%td%启用%/td
%}
%JSP缺点 列举部分缺点如下 书写麻烦特别是对于复杂的页面阅读麻烦复杂度高运行需要依赖各种环境比如JRE、JSP容器、JavaEE等占用内存和磁盘JSP会自动生成.java和.class文件占磁盘运行的是.class文件占内存调试困难出错后需要找到自动生成的.java文件进行调试不利于团队写作前端人员不会Java后端人员不精Html由于以上缺点JSP被HtmlAJAX逐渐代替 解决方式 不直接在JSP中写Java代码而是利用Servlet和JSP的结合即Java代码写在Servlet中进行逻辑处理封装数据而JSP利用EL表达式 和JSTL标签 来获取数据并进行遍历展现数据 EL表达式 用来替换JSP中获取数据的Java代码JSTL标签 用来替换循环、遍历的Java代码
EL表达式 定义 Expression Language表达式语言用于简化JSP页面内的Java代码 主要功能获取数据 语法${key} ${brands}获取request域中存储的key为brands的数据 JavaWeb中四大域对象 page当前页面有效request当前请求有效session当前会话有效application当前应用有效注意EL表达式获取数据时会依次从这4个域中寻找直到找到为止 简单示例 Step1在at.guigu.web包下创建ServletDemo1类将准备数据放入最终代码如下 package at.guigu.web;import at.guigu.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(/eldemo1)
public class ServletDemo1 extends HttpServlet {Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1 准备数据模拟查询数据库并获取数据ListBrand brands new ArrayList();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.jsprequest.getRequestDispatcher(/el-demo.jsp).forward(request, response);}Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
}Step2创建el-demo.jsp文件具体代码如下 注意要在JSP页面顶部%...%标签体内加上isELIgnoredfalse作用是防止Tomcat配置禁用EL表达式 % page contentTypetext/html;charsetUTF-8 languagejava isELIgnoredfalse %
htmlheadtitleTitle/title/headbody!--获取request域中存储brands的数据--${brands}/body
/htmlTomcat运行该Web项目后运行截图如下
JSTL标签 定义 JSTL即JSP Standarded Tag Library是Java 服务器页面标准标签库使用标签取代JSP页面上的Java代码它为 JSP 页面提供了一组标准的标签库用于简化 JSP 页面中的常见任务例如条件判断、循环迭代、字符串操作、国际化、数据库访问等。 JSTL标签 标签解释c:out用于在JSP中显示数据相当于%...c:set用于保存数据c:remove用于删除数据c:catch用来处理产生错误的异常情况并将错误信息储存起来c:if与java中的if一样c:choose本身只当作c:when和c:otherwise的父标签c:whenc:choose的子标签用来判断条件是否成立c:otherwisec:choose的子标签接在c:when标签后当c:when标签判断为false时被执行c:import检索一个绝对或相对URL然后将其内容暴露给页面c:forEach基础迭代标签接受多种集合类型c:forTokens根据指定的分隔符来分割内容并迭代输出c:param用来给包含或重定向的页面传递参数c:redirect重定向至一个新的URLc:url使用可选的查询参数来创造一个URL JSTL标签使用步骤 Step1 在Web项目的pom.xml文件中导入坐标依赖 dependencygroupIdjstl/groupIdartifactIdjstl/artifactIdversion1.2/version
/dependency
dependencygroupIdtaglibs/groupIdartifactIdstandard/artifactIdversion1.1.2/version
/dependencyStep2 在JSP页面上引入JSTL标签库% taglib prefixc urihttp://java.sun.com/jsp/jstl/core % 如下所示 % taglib prefixc urihttp://java.sun.com/jsp/jstl/core %
% page contentTypetext/html;charsetUTF-8 languagejava %
htmlheadtitleTitle/title/headbody/body
/htmlStep3 使用标签
使用标签—条件标签
c:if标签
定义相当于if判断
该标签中必有的属性解释test该属性的属性值为逻辑表达式结果若为true则执行该标签体中的内容 简单示例jstl-demo1.jsp文件代码如下 % taglib prefixc urihttp://java.sun.com/jsp/jstl/core %
% page contentTypetext/html;charsetUTF-8 languagejava %
htmlheadtitleTitle/title/headbodyc:if testtrueh1判断为true/h1/c:if/body
/htmlc:if标签通常与EL表达式联合使用来执行对应的代码代码示例如下 ServletDemo1.java代码如下 package at.guigu.web;import at.guigu.pojo.Brand;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.ArrayList;
import java.util.List;WebServlet(/jstldemo2)
public class ServletDemo2 extends HttpServlet {Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1 准备数据模拟查询数据库并获取数据ListBrand brands new ArrayList();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);//用来测试c:if标签request.setAttribute(status, 1);//3 转发到el-demo.jsprequest.getRequestDispatcher(/jstl-demo2.jsp).forward(request, response);}Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
}jstl-demo2.jsp文件代码如下 % taglib prefixc urihttp://java.sun.com/jsp/jstl/core %
% page contentTypetext/html;charsetUTF-8 languagejava isELIgnoredfalse %
htmlheadtitleTitle/title/headbodyc:if test${status1}h1满足status1则输出该条html语句/h1/c:if/body
/htmlc:choose、c:when、c:otherwise 以上三个标签联合使用用于实现多条件分支的逻辑控制类似于 Java 中的 switch 语句或 if-else-if 结构。 三个标签解释 c:choose 该标签本身没有属性可包含一个或多个 c:when 标签可以选择性 地包含一个 c:otherwise 标签 c:when标签 用于定义每个条件分支具有唯一的必需属性test c:otherwise标签 用于定义在所有 c:when 条件都不满足时应该执行的代码块该标签没有属性且必须位于 c:choose 标签内并且通常放在所有 c:when 标签之后该标签内的内容在所有 c:when 条件都为 false 时执行 代码示例1 % taglib prefixc urihttp://java.sun.com/jsp/jstl/core %
% page contentTypetext/html;charsetUTF-8 languagejava isELIgnoredfalse %
c:choosec:when test${user.age 18}p您是未成年人。/p/c:whenc:when test${user.age 18 and user.age 65}p您是成年人。/p/c:whenc:otherwisep您是老年人。/p/c:otherwise
/c:choose如果 user.age 小于 18则显示“您是未成年人。如果 user.age 在 18 到 65 之间含则显示“您是成年人。如果以上两个条件都不满足即 user.age 大于 65则显示“您是老年人。 代码示例2 % taglib prefixc urihttp://java.sun.com/jsp/jstl/core %
% page contentTypetext/html;charsetUTF-8 languagejava isELIgnoredfalse %
c:choosec:when test${user.role admin}p欢迎管理员!/p/c:whenc:when test${user.role user}p欢迎普通用户!/p/c:whenc:otherwisep欢迎访客请登录。/p/c:otherwise
/c:choose如果 user.role 是 admin则显示“欢迎管理员!”如果 user.role 是 user则显示“欢迎普通用户!”如果以上两个条件都不满足则执行 c:otherwise 标签内的内容显示“欢迎访客请登录。
使用标签------迭代标签c:forEach
该标签的属性解释items要迭代的集合即被遍历的容器。可以是数组、集合、映射等var每次迭代时存储当前项的变量名即遍历产生的临时变量varStatus一个变量用于存储迭代状态即遍历状态对象可选(注意 该属性的属性值字符串可随意写属性值.index序号从0开始属性值.count序号从1开始)begin迭代的起始索引可选end迭代的结束索引可选step每次迭代的步长可选
定义相当于for循环
增强for循环 增强for循环代码示例 Brand类代码 package at.guigu.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, 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;}Overridepublic String toString() {return Brand{ id id , brandName brandName \ , companyName companyName \ , ordered ordered , description description \ , status status };}
}JstlServletDemo3代码 package at.guigu.web;import at.guigu.pojo.Brand;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.ArrayList;
import java.util.List;WebServlet(/jstldemo3)
public class JstlServletDemo3 extends HttpServlet {Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1 准备数据模拟查询数据库并获取数据ListBrand brands new ArrayList();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);//用来测试c:if标签request.setAttribute(status, 1);//3 转发到el-demo.jsprequest.getRequestDispatcher(/jstl-demo3.jsp).forward(request, response);}Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
}jstl-demo3.jsp代码 % taglib prefixc urihttp://java.sun.com/jsp/jstl/core %
% page contentTypetext/html;charsetUTF-8 languagejava isELIgnoredfalse %
htmlheadtitleTitle/title/headbodyinput typebutton value新增brhrtable border1 cellspacing0trth序号/thth品牌名称/thth企业名称/thth排序/thth品牌介绍/thth状态/thth操作/th/trc:forEach items${brands} varbrandtr aligncentertd${brand.id}/tdtd${brand.brandName}/tdtd${brand.companyName}/tdtd${brand.ordered}/tdtd${brand.description}/tdc:choosec:when test${brand.status1}td启用/td/c:whenc:otherwisetd禁用/td/c:otherwise/c:choosetda href#修改/a a href#删除/a/td/tr/c:forEach/table/body
/html注意 EL表达式${对象名.属性名} 会被系统自动解析并调用对应的getXXX()方法来返回对应的值 上述运行截图中序号对应的是数据库中的主键id这就会有一个弊端如果删除优衣库则由于主键是唯一的不会分配给其它品牌所以最终浏览器的页面上的品牌三只松鼠和小米的序号仍为1、3并不会变成1、2 为了解决该问题可使用varStatus属性如下jsp文件代码所示 示例一序号从0开始 %--Created by IntelliJ IDEA.User: 10195Date: 2024/6/28Time: 9:19To change this template use File | Settings | File Templates.
--%
% taglib prefixc urihttp://java.sun.com/jsp/jstl/core %
% page contentTypetext/html;charsetUTF-8 languagejava isELIgnoredfalse %
htmlheadtitleTitle/title/headbodyinput typebutton value新增brhrtable border1 cellspacing0trth序号/thth品牌名称/thth企业名称/thth排序/thth品牌介绍/thth状态/thth操作/th/trc:forEach items${brands} varbrand varStatusxuhaotr aligncentertd${xuhao.index}/tdtd${brand.brandName}/tdtd${brand.companyName}/tdtd${brand.ordered}/tdtd${brand.description}/tdc:choosec:when test${brand.status1}td启用/td/c:whenc:otherwisetd禁用/td/c:otherwise/c:choosetda href#修改/a a href#删除/a/td/tr/c:forEach/table/body
/html示例二序号从1开始 % taglib prefixc urihttp://java.sun.com/jsp/jstl/core %
% page contentTypetext/html;charsetUTF-8 languagejava isELIgnoredfalse %
htmlheadtitleTitle/title/headbodyinput typebutton value新增brhrtable border1 cellspacing0trth序号/thth品牌名称/thth企业名称/thth排序/thth品牌介绍/thth状态/thth操作/th/trc:forEach items${brands} varbrand varStatusxuhaotr aligncentertd${xuhao.count}/tdtd${brand.brandName}/tdtd${brand.companyName}/tdtd${brand.ordered}/tdtd${brand.description}/tdc:choosec:when test${brand.status1}td启用/td/c:whenc:otherwisetd禁用/td/c:otherwise/c:choosetda href#修改/a a href#删除/a/td/tr/c:forEach/table/body
/html普通for循环 作用可用来定义分页工具条 代码示例 Brand及JstlServletDemo3代码与增强for循环一样此处省略 jstl-demo3.jsp代码 % taglib prefixc urihttp://java.sun.com/jsp/jstl/core %
% page contentTypetext/html;charsetUTF-8 languagejava isELIgnoredfalse %
htmlheadtitleTitle/title/headbodyinput typebutton value新增brhrtable border1 cellspacing0trth序号/thth品牌名称/thth企业名称/thth排序/thth品牌介绍/thth状态/thth操作/th/trc:forEach items${brands} varbrand varStatusxuhaotr aligncentertd${xuhao.count}/tdtd${brand.brandName}/tdtd${brand.companyName}/tdtd${brand.ordered}/tdtd${brand.description}/tdc:choosec:when test${brand.status1}td启用/td/c:whenc:otherwisetd禁用/td/c:otherwise/c:choosetda href#修改/a a href#删除/a/td/tr/c:forEach/tablehrc:forEach begin1 end10 step1 varia href#${i}/a/c:forEach/body
/html理论知识
MVC模式 定义MVC是一种分层开发的模式 MModel即业务模型用于处理业务VView即视图用于页面展示CController即控制器用于处理请求调用模型和视图 MVC模式实现过程 浏览器向服务器端请求数据时会先请求控制器控制器调用模型来获取数据之后控制器会将数据传给视图并由视图响应给浏览器实现最终的页面展示 特点 由Servlet充当控制器JavaBean充当模型JSP充当视图职责单一互不影响有利于分工协作有利于组件重用
三层架构 解释将一个完整的项目分为三个层面 表现层接收请求封装数据调用业务逻辑层响应数据 包名默认为at.guigu.web或at.guigu.controller对应的框架为SpringMVC或Struts2 业务逻辑层对业务逻辑进行封装组合数据访问层层中的基本功能从而形成复杂的业务逻辑功能 包名默认为at.guigu.service对应的框架为Spring解释假设现在数据访问层有多个增删改查方法若表现层有多个实现Servlet的类需要用到其中增和删两个方法此时若在实现类中频繁写重复代码就造成了冗余所以我们可以将其封装起来作为一个业务方法以此来供实现Servlet接口的实现类使用这样可增加代码的复用性 数据访问层持久层对数据库进行CRUD增删改查的基本操作 包名默认为at.guigu.dao或at.guigu.mapper 若我们用到了MyBatis技术则使用后者反之使用前者 对应的框架为MyBatis或Hibername 三层架构实现过程 浏览器向服务器端请求数据时会先请求表现层的控制器即Servlet然后控制器会调用业务逻辑层的代码这些代码组装了数据访问层的CRUD等基本功能来获取数据库中的数据并将数据返回给表现层中的控制器即Swervlet然后再由控制器即Servlet对数据进行封装放到request域中传给视图即JSP最终由视图即JSP将响应数据返回给浏览器使其展现在页面上 MVC模式和三层架构的区别
案例 注意本案例已提交到Gitee可自行下载https://gitee.com/cgrs572/brand-demo.git 环境准备 创建新的Web项目BrandDemo引入坐标在pom.xml文件中引入坐标依赖并配置Tomcat可详见Tomcat部分 需要的坐标依赖有mybatis、mysql驱动、servlet、jsp、jstl 需要的插件有Tomcat插件 完整pom.xml文件如下 project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsdmodelVersion4.0.0/modelVersiongroupIdorg.example/groupIdartifactIdBrandDemo/artifactIdpackagingwar/packagingversion1.0-SNAPSHOT/versionnameBrandDemo Maven Webapp/nameurlhttp://maven.apache.org/urldependenciesdependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion3.8.1/versionscopetest/scope/dependency!--MyBatis依赖--dependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactIdversion3.5.16/version/dependency!--mysql驱动--dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.33/version/dependency!--Servlet依赖--dependencygroupIdjavax.servlet/groupIdartifactIdjavax.servlet-api/artifactIdversion3.1.0/versionscopeprovided/scope!--依赖范围关键字provided:在编译环境和测试环境有效但在真正运行时就不会在使用该jar包--/dependency!--JSP依赖--dependencygroupIdjavax.servlet.jsp/groupIdartifactIdjsp-api/artifactIdversion2.2/versionscopeprovided/scope/dependency!--jstl依赖--dependencygroupIdjstl/groupIdartifactIdjstl/artifactIdversion1.2/version/dependencydependencygroupIdtaglibs/groupIdartifactIdstandard/artifactIdversion1.1.2/version/dependency/dependenciesbuildfinalNameBrandDemo/finalNameplugins!-- Tomcat插件 --plugingroupIdorg.apache.tomcat.maven/groupIdartifactIdtomcat7-maven-plugin/artifactIdversion2.2/version/plugin/plugins/build
/project创建三层架构包结构 创建数据库表tb_brand并使IDEA与数据库建立连接SQL代码如下 DROP TABLE IF EXISTS tb_brand;-- 创建品牌表brand
CREATE TABLE IF NOT EXISTS 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;创建实体类Brand此为Pojo类 存放对数据库中数据封装的对象代码如下 package at.guigu.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, 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;}Overridepublic String toString() {return Brand{ id id , brandName brandName \ , companyName companyName \ , ordered ordered , description description \ , status status };}
}MyBrtis基础环境配置 在mapper包下创建BrandMapper接口 在项目的源代码配置文件目录即main包下的resources目录下创建多层目录多层目录对应Mapper接口所在的多层包然后再该包中创建BrandMapper.xmlSQL映射文件基本代码如下 ?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd!--namespace名称空间
--
mapper namespaceat.guigu.mapper.BrandMapper!--结果映射--resultMap idbrandResultMap typebrand!--由于id为主键且数据库中的字段名和对应结果映射的目标类中的属性名一样所以此处不需要主键映射只需进行非主键映射即可--result columnbrand_name propertybrandName/result columncompany_name propertycompanyName//resultMap/mapper在项目的源代码配置文件目录即main包下的resources目录下创建MyBatis核心配置文件mybatis-config.xml代码如下 ?xml version1.0 encodingUTF-8 ?
!DOCTYPE configurationPUBLIC -//mybatis.org//DTD Config 3.0//ENhttps://mybatis.org/dtd/mybatis-3-config.dtd
configuration!--设置别名--typeAliasespackage nameat.guigu.pojo//typeAliasesenvironments defaultdevelopmentenvironment iddevelopmenttransactionManager typeJDBC/dataSource typePOOLED!--数据库 连接信息--property namedriver valuecom.mysql.cj.jdbc.Driver/property nameurl valuejdbc:mysql://localhost:3306/mybatis?useUnicodetrueamp;characterEncodingutf-8amp;useSSLfalseamp;serverTimezoneAsia/Shanghai/property nameusername valueroot/property namepassword value123456//dataSource/environment/environmentsmappers!--加载SQL映射文件传入sql映射文件的路径--
!-- mapper resourceat/guigu/mapper/BrandMapper.xml/--package nameat.guigu.mapper//mappers
/configuration查询所有 解释页面上有一个“查询所有”的超链接单击该链接即显示出查询数据如图所示 要完成该问则需满足三层架构各层需要做的工作如下所示 Dao层/Map层 Step1 BrandMapper接口中写入查询所有数据的方法 package at.guigu.mapper;import at.guigu.pojo.Brand;
import java.util.List;public interface BrandMapper {//查询并返回所有商品/*Select(select * from tb_brand)ResultMap(brandResultMap)*/ListBrand selectAll();
}注意 对数据库中的字段进行结果映射后若想要用注解方式输写SQL语句则需要另外加上注解ResultMap(brandResultMap)才能使结果映射生效结果映射可详见MyBatis那一节由于我在SQL映射文件中输入SQL语句所以不需要改代码中的两个注解若使用MyBatis注解开发即SQL语句写在注解中则需要加上以上两个注解 Step2 在对应的SQL映射文件BrandMapper.xml中写入SQL语句 ?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd!--namespace名称空间
--
mapper namespaceat.guigu.mapper.BrandMapper!--结果映射--resultMap idbrandResultMap typebrand!--由于id为主键且数据库中的字段名和对应结果映射的目标类中的属性名一样所以此处不需要主键映射只需进行非主键映射即可--result columnbrand_name propertybrandName/result columncompany_name propertycompanyName//resultMap!--id为sql语句的唯一标识resultType为对应sql语句执行完毕后返回结果的类型--select idselectAll resultMapbrandResultMapselect * from tb_brand;/select
/mapperService层 由于Service层中的类均需要调用Mapper接口中的方法那么该层中的类就都需要载核心配置文件来获取SqlSessionFactorySQL连接工厂对象所以就可以将SqlSessionFactory封装为一个工具类。所以在完善Service层之前需要先在util包下将工具类SqlSessionFactoryUtils创建好代码如下 package at.guigu.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 {//配置mybatis-config.xml文件路径。注意若该文件直接在resources目录下则直接写文件名即可String resource mybatis-config.xml;//利用Resources类中的静态方法将配置文件加载到内存InputStream inputStream Resources.getResourceAsStream(resource);//获取SqlSessionFactory对象sqlSessionFactory new SqlSessionFactoryBuilder().build(inputStream);} catch (IOException e) {e.printStackTrace();}}public static SqlSessionFactory getSqlSessionFactory() {return sqlSessionFactory;}
}Step1 在service包下创建BrandService类来调用mapper包下的BrandMapper接口中的方法代码如下 注意获取SqlSessionFactory对象的代码放在了成员变量的位置这样所有方法可共用该对象并不需要重复获取 package at.guigu.service;import at.guigu.mapper.BrandMapper;
import at.guigu.pojo.Brand;
import at.guigu.util.SqlSessionFactoryUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;import java.io.IOException;
import java.util.List;public class BrandService {//1 获取SqlSessionFactory对象SqlSessionFactory sqlSessionFactory SqlSessionFactoryUtils.getSqlSessionFactory();public ListBrand getAll() throws IOException {//2 获取SqlSession对象执行SQL语句//2.1 获取SqlSession对象SqlSession sqlSession sqlSessionFactory.openSession();//2.2 获取Mapper接口UserMapper的代理对象BrandMapper brandMapper sqlSession.getMapper(BrandMapper.class);//2.3 执行sql语句ListBrand brands brandMapper.selectAll();sqlSession.close();return brands;}
}Web层 Step1由于是通过单击页面index.html上查询所有从而显示出查询数据所以首先要创建一个index.html页面代码如下 注意html文件名默认为index时若我们不输入资源则运行该Web项目后浏览器会默认访问到该html页面 !DOCTYPE html
html langenheadmeta charsetUTF-8titleTitle/title/headbodya href/BrandDemo/selectAllServlet查询所有/a/body
/htmlStep2创建SelectAllServlet类且代码如下 注意创建一个私有的BrandService对象应将其放在成员变量的位置因为对于大工程来说可能会多次用到Service对象 package at.guigu.web;import at.guigu.pojo.Brand;
import at.guigu.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 {//1 创建一个私有的BrandService对象private BrandService brandService new BrandService();Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//2 调用BrandService中的方法查询所有数据ListBrand brands brandService.getAll();//2 存储数据到Request域中request.setAttribute(brands, brands);//3 转发到brand.jsp中request.getRequestDispatcher(/brand.jsp).forward(request, response);}Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
}Step3在Web项目核心目录下创建brand.jsp且代码如下 % taglib prefixc urihttp://java.sun.com/jsp/jstl/core %
% page contentTypetext/html;charsetUTF-8 languagejava isELIgnoredfalse %
htmlheadtitleTitle/title/headbodyinput typebutton value新增brhrtable border1 cellspacing0trth序号/thth品牌名称/thth企业名称/thth排序/thth品牌介绍/thth状态/thth操作/th/trc:forEach items${brands} varbrand varStatusxuhaotr aligncentertd${xuhao.count}/tdtd${brand.brandName}/tdtd${brand.companyName}/tdtd${brand.ordered}/tdtd${brand.description}/tdc:choosec:when test${brand.status1}td启用/td/c:whenc:otherwisetd禁用/td/c:otherwise/c:choosetda href#修改/a a href#删除/a/td/tr/c:forEach/table/body
/html三层架构都准备完毕后Tomcat启动该Web项目Web项目启动成功后会默认运行index.html文件然后单击查询所有即可跳转到另一页面显示出查询数据如图所示
添加 解释 单击新增按钮后跳转到添加品牌的页面该页面为addBrand.jsp然后输入要添加的品牌信息后单击提交提交后浏览器将请求数据提交到服务器的Servlet然后将数据保存到数据库中最后重新展示一下查询所有的页面即可显示出最新的所有数据 各层需要做的工作如图所示 Dao层/Map层 Step1 BrandMapper接口中写入添加数据的方法 package at.guigu.mapper;import at.guigu.pojo.Brand;
import at.guigu.service.BrandService;
import org.apache.ibatis.annotations.ResultMap;
import org.apache.ibatis.annotations.Select;import java.util.List;public interface BrandMapper {//查询并返回所有商品/*Select(select * from tb_brand)ResultMap(brandResultMap)*/ListBrand selectAll();//添加商品/*Select(insert into tb_brand values(#{brandName},#{companyName},#{ordered},#{description},#{status}))*/void add(Brand brand);
}注意 对数据库中的字段进行结果映射后若想要用注解方式输写 查询 的SQL语句则需要另外加上注解ResultMap(brandResultMap)才能使结果映射生效结果映射可详见MyBatis那一节由于我在SQL映射文件中输入 查询 的SQL语句所以不需要代码中的两个注解若使用MyBatis注解开发即SQL语句写在注解中则需要加上以上两个注解 Step2 在对应的SQL映射文件BrandMapper.xml中写入SQL语句 ?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd!--namespace名称空间
--
mapper namespaceat.guigu.mapper.BrandMapper!--结果映射--resultMap idbrandResultMap typebrand!--由于id为主键且数据库中的字段名和对应结果映射的目标类中的属性名一样所以此处不需要主键映射只需进行非主键映射即可--result columnbrand_name propertybrandName/result columncompany_name propertycompanyName//resultMap!--id为sql语句的唯一标识resultType为对应sql语句执行完毕后返回结果的类型--select idselectAll resultMapbrandResultMapselect * from tb_brand;/selectinsert idaddinsert into tb_brand values (null, #{brandName}, #{companyName}, #{ordered}, #{description}, #{status});/insert
/mapperService层 工具类SqlSessionFactoryUtils代码省略详见查询所有中的SqlSessionFactoryUtils代码 Step1 在service包下创建BrandService类来调用mapper包下的BrandMapper接口中的方法代码如下 package at.guigu.service;import at.guigu.mapper.BrandMapper;
import at.guigu.pojo.Brand;
import at.guigu.util.SqlSessionFactoryUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;import java.io.IOException;
import java.util.List;public class BrandService {//1 获取SqlSessionFactory对象SqlSessionFactory sqlSessionFactory SqlSessionFactoryUtils.getSqlSessionFactory();/*** 查询所有* return* throws IOException*/public ListBrand getAll() throws IOException {//2 获取SqlSession对象执行SQL语句//2.1 获取SqlSession对象SqlSession sqlSession sqlSessionFactory.openSession();//2.2 获取Mapper接口UserMapper的代理对象BrandMapper brandMapper sqlSession.getMapper(BrandMapper.class);//2.3 执行sql语句ListBrand brands brandMapper.selectAll();sqlSession.close();return brands;}/*** 添加品牌* param brand*/public void add(Brand brand){//2 获取SqlSession对象执行SQL语句//2.1 获取SqlSession对象SqlSession sqlSession sqlSessionFactory.openSession();//2.2 获取Mapper接口UserMapper的代理对象BrandMapper brandMapper sqlSession.getMapper(BrandMapper.class);//2.3 执行添加品牌的sql语句brandMapper.add(brand);//3 注意增删改的SQL语句需要手动提交事务让其生效sqlSession.commit();//释放资源sqlSession.close();}
}Web层 Step1在Web项目核心目录下创建addBrand.jsp且代码如下 % page contentTypetext/html;charsetUTF-8 languagejava %
htmlheadtitle添加品牌/title/headbodyh3添加品牌/h3!--action的属性值为浏览器提交到服务器的资源路径--form action/BrandDemo/addServlet methodpost品牌名称input namebrandNamebr企业名称input namecompanyNamebr排序input nameorderedbr描述信息testarea rows5 cols20 namedescription/testareabr状态input typeradio namestatus value0禁用input typeradio namestatus value1禁用brinput typesubmit value提交/form/body
/htmlStep2通过JavaScript代码来为brand.jsp中的新增按钮添加鼠标单击事件 可详见前端知识点汇总单击新增按钮后页面跳转到添加品牌的页面即addBrand.jsp代码如下所示 % taglib prefixc urihttp://java.sun.com/jsp/jstl/core %
% page contentTypetext/html;charsetUTF-8 languagejava isELIgnoredfalse %
htmlheadtitleTitle/title/headbodyinput typebutton value新增 idaddbrhrtable border1 cellspacing0trth序号/thth品牌名称/thth企业名称/thth排序/thth品牌介绍/thth状态/thth操作/th/trc:forEach items${brands} varbrand varStatusxuhaotr aligncentertd${xuhao.count}/tdtd${brand.brandName}/tdtd${brand.companyName}/tdtd${brand.ordered}/tdtd${brand.description}/tdc:choosec:when test${brand.status1}td启用/td/c:whenc:otherwisetd禁用/td/c:otherwise/c:choosetda href#修改/a a href#删除/a/td/tr/c:forEach/tablescriptdocument.getElementById(add).onclick function () {//addBrand.jsp的路径location.href /BrandDemo/addBrand.jsp;}/script/body
/htmlStep3创建AddServlet类且代码如下 package at.guigu.web;import at.guigu.pojo.Brand;
import at.guigu.service.BrandService;import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;WebServlet(/addServlet)
public class AddServlet extends HttpServlet {//1 创建一个私有的BrandService对象private BrandService brandService new BrandService();Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//添加数据时注意要处理中文乱码问题//处理post请求乱码request.setCharacterEncoding(UTF-8);//2 接收表单提交的数据并封装为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);//将字符串数字先转换为Integer类型在存入Brand中brand.setOrdered(Integer.parseInt(ordered));brand.setDescription(description);brand.setStatus(Integer.parseInt(status));//3 调用brandService完成添加brandService.add(brand);//转发到查询所有的Servletrequest.getRequestDispatcher(/selectAllServlet).forward(request, response);}Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
}三层架构都准备完毕后Tomcat启动该Web项目Web项目启动成功后会默认运行index.html文件然后单击查询所有即可跳转到另一页面显示出查询数据之后单击新增按钮填写完新增数据后单击提交按钮数据被提交到数据库保存然后页面会自动跳转到查询所有的页面显示出所有品牌数据如图所示
修改——回显数据 解释 单击对应品牌的修改按钮后会跳转到新的页面该页面为update.jsp该页面会显示你要修改的品牌上次所保存的内容 各层需要做的工作如图所示 Dao层/Map层 Step1 BrandMapper接口中写入修改数据的方法 package at.guigu.mapper;import at.guigu.pojo.Brand;
import at.guigu.service.BrandService;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.ResultMap;
import org.apache.ibatis.annotations.Select;import java.util.List;public interface BrandMapper {/*Select(select * from tb_brand)ResultMap(brandResultMap)*/ListBrand selectAll();//Insert(insert into tb_brand values (null, #{brandName}, #{companyName}, #{ordered}, #{description}, #{status}))void add(Brand brand);//修改——回显数据void selectById(int id);
}Step2 在对应的SQL映射文件BrandMapper.xml中写入SQL语句 ?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd!--namespace名称空间
--
mapper namespaceat.guigu.mapper.BrandMapper!--结果映射--resultMap idbrandResultMap typebrand!--由于id为主键且数据库中的字段名和对应结果映射的目标类中的属性名一样所以此处不需要主键映射只需进行非主键映射即可--result columnbrand_name propertybrandName/result columncompany_name propertycompanyName//resultMap!--id为sql语句的唯一标识resultType为对应sql语句执行完毕后返回结果的类型--!--查询所有品牌--select idselectAll resultMapbrandResultMapselect * from tb_brand;/select!--添加品牌--insert idaddinsert into tb_brand values (null, #{brandName}, #{companyName}, #{ordered}, #{description}, #{status});/insert!--修改——回显数据根据id查询--select idselectById resultMapbrandResultMapselect * from tb_brand where id #{id};/select
/mapperService层 工具类SqlSessionFactoryUtils代码省略详见查询所有中的SqlSessionFactoryUtils代码 Step1 在service包下创建BrandService类来调用mapper包下的BrandMapper接口中的方法代码如下 package at.guigu.service;import at.guigu.mapper.BrandMapper;
import at.guigu.pojo.Brand;
import at.guigu.util.SqlSessionFactoryUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;import java.io.IOException;
import java.util.List;public class BrandService {//1 获取SqlSessionFactory对象SqlSessionFactory sqlSessionFactory SqlSessionFactoryUtils.getSqlSessionFactory();/*** 查询所有* return* throws IOException*/public ListBrand getAll() throws IOException {//2 获取SqlSession对象执行SQL语句//2.1 获取SqlSession对象SqlSession sqlSession sqlSessionFactory.openSession();//2.2 获取Mapper接口UserMapper的代理对象BrandMapper brandMapper sqlSession.getMapper(BrandMapper.class);//2.3 执行sql语句ListBrand brands brandMapper.selectAll();sqlSession.close();return brands;}/*** 添加品牌* param brand*/public void add(Brand brand){//2 获取SqlSession对象执行SQL语句//2.1 获取SqlSession对象SqlSession sqlSession sqlSessionFactory.openSession();//2.2 获取Mapper接口UserMapper的代理对象BrandMapper brandMapper sqlSession.getMapper(BrandMapper.class);//2.3 执行添加品牌的sql语句brandMapper.add(brand);//3 注意增删改的SQL语句需要手动提交事务让其生效sqlSession.commit();//释放资源sqlSession.close();}/*** 修改——回显数据根据id查询* param id* return* throws IOException*/public Brand selectById(int id) throws IOException {//2 获取SqlSession对象执行SQL语句//2.1 获取SqlSession对象SqlSession sqlSession sqlSessionFactory.openSession();//2.2 获取Mapper接口UserMapper的代理对象BrandMapper brandMapper sqlSession.getMapper(BrandMapper.class);//2.3 执行修改——回显数据的sql语句Brand brand brandMapper.selectById(id);//释放资源sqlSession.close();return brand;}
}Web层 Step1在Web项目核心目录下创建update.jsp且代码如下 %--Created by IntelliJ IDEA.User: 10195Date: 2024/6/30Time: 16:49To change this template use File | Settings | File Templates.
--%
% taglib prefixc urihttp://java.sun.com/jsp/jstl/core %
% page contentTypetext/html;charsetUTF-8 languagejava isELIgnoredfalse %
htmlheadtitle修改品牌/title/headbodyh3修改品牌/h3!--action的属性值为浏览器提交到服务器的资源路径--form action/BrandDemo/addServlet methodpost品牌名称input namebrandName value${brand.brandName}br企业名称input namecompanyName value${brand.companyName}br排序input nameordered value${brand.ordered}br描述信息textarea rows5 cols20 namedescription${brand.description}/textareabr状态c:choosec:when test${brand.status 0}input typeradio namestatus value0 checked禁用input typeradio namestatus value1启用br/c:whenc:otherwiseinput typeradio namestatus value0禁用input typeradio namestatus value1 checked启用br/c:otherwise/c:chooseinput typesubmit value提交/form/body
/htmlStep2通过JavaScript代码来为brand.jsp中的修改按钮添加鼠标单击事件 可详见前端知识点汇总单击修改按钮后页面会根据id跳转到对应品牌的页面即.jsp代码如下所示 %--Created by IntelliJ IDEA.User: 10195Date: 2024/6/28Time: 19:40To change this template use File | Settings | File Templates.
--%
% taglib prefixc urihttp://java.sun.com/jsp/jstl/core %
% page contentTypetext/html;charsetUTF-8 languagejava isELIgnoredfalse %
htmlheadtitleTitle/title/headbodyinput typebutton value新增 idaddbrhrtable border1 cellspacing0trth序号/thth品牌名称/thth企业名称/thth排序/thth品牌介绍/thth状态/thth操作/th/trc:forEach items${brands} varbrand varStatusxuhaotr aligncentertd${xuhao.count}/tdtd${brand.brandName}/tdtd${brand.companyName}/tdtd${brand.ordered}/tdtd${brand.description}/tdc:choosec:when test${brand.status1}td启用/td/c:whenc:otherwisetd禁用/td/c:otherwise/c:choosetda href/BrandDemo/selectByIdServlet?id${brand.id}修改/a a href#删除/a/td/tr/c:forEach/tablescriptdocument.getElementById(add).onclick function () {//addBrand.jsp的路径location.href /BrandDemo/addBrand.jsp;}/script/body
/htmlStep3创建SelectByIdServlet类且代码如下 package at.guigu.web;import at.guigu.pojo.Brand;
import at.guigu.service.BrandService;import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;WebServlet(/selectByIdServlet)
public class SelectByIdServlet extends HttpServlet {//1 创建一个私有的BrandService对象private BrandService brandService new BrandService();Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//2 接收idString id request.getParameter(id);//3 调用对应的Service查询Brand brand brandService.selectById(Integer.parseInt(id));//4 将该Brand对象存储到request域中request.setAttribute(brand, brand);//5 转发到update.jsp中request.getRequestDispatcher(/update.jsp).forward(request,response);}Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
}三层架构都准备完毕后Tomcat启动该Web项目Web项目启动成功后会默认运行index.html文件然后单击查询所有即可跳转到另一页面显示出查询数据之后单击修改按钮后会自动跳转到修改品牌页面如图所示
修改——修改数据 解释修改数据是在回显数据的基础上进行操作的即对update.jsp页面的表单进行修改后单击提交按钮将数据保存到数据库中最后重现展示一下查询所有的页面即可显示出最新的所有数据 各层需要做的工作如图所示 Dao层/Map层 Step1 BrandMapper接口中写入修改数据的方法 package at.guigu.mapper;import at.guigu.pojo.Brand;
import at.guigu.service.BrandService;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.ResultMap;
import org.apache.ibatis.annotations.Select;import java.util.List;public interface BrandMapper {/*Select(select * from tb_brand)ResultMap(brandResultMap)*/ListBrand selectAll();//Insert(insert into tb_brand values (null, #{brandName}, #{companyName}, #{ordered}, #{description}, #{status}))void add(Brand brand);/*** //修改——回显数据根据id查询* param id* return*//*Select(select * from tb_brand where id #{id})ResultMap(brandResultMap)*/Brand selectById(int id);//修改——修改数据void update(Brand brand);
}Step2 在对应的SQL映射文件BrandMapper.xml中写入SQL语句 ?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd!--namespace名称空间
--
mapper namespaceat.guigu.mapper.BrandMapper!--结果映射--resultMap idbrandResultMap typebrand!--由于id为主键且数据库中的字段名和对应结果映射的目标类中的属性名一样所以此处不需要主键映射只需进行非主键映射即可--result columnbrand_name propertybrandName/result columncompany_name propertycompanyName//resultMap!--id为sql语句的唯一标识resultType为对应sql语句执行完毕后返回结果的类型--!--查询所有品牌--select idselectAll resultMapbrandResultMapselect * from tb_brand;/select!--添加品牌--insert idaddinsert into tb_brand values (null, #{brandName}, #{companyName}, #{ordered}, #{description}, #{status});/insert!--修改——回显数据根据id查询--select idselectById resultMapbrandResultMapselect * from tb_brand where id #{id};/select!--修改——修改数据--update idupdateupdate tb_brandset brand_name#{brandName},company_name#{companyName},ordered#{ordered},description#{description},status#{status}where id#{id};/update
/mapperService层 工具类SqlSessionFactoryUtils代码省略详见查询所有中的SqlSessionFactoryUtils代码 Step1 在service包下创建BrandService类来调用mapper包下的BrandMapper接口中的方法代码如下 package at.guigu.service;import at.guigu.mapper.BrandMapper;
import at.guigu.pojo.Brand;
import at.guigu.util.SqlSessionFactoryUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;import java.io.IOException;
import java.util.List;public class BrandService {//1 获取SqlSessionFactory对象SqlSessionFactory sqlSessionFactory SqlSessionFactoryUtils.getSqlSessionFactory();/*** 查询所有* return* throws IOException*/public ListBrand getAll() throws IOException {//2 获取SqlSession对象执行SQL语句//2.1 获取SqlSession对象SqlSession sqlSession sqlSessionFactory.openSession();//2.2 获取Mapper接口UserMapper的代理对象BrandMapper brandMapper sqlSession.getMapper(BrandMapper.class);//2.3 执行sql语句ListBrand brands brandMapper.selectAll();sqlSession.close();return brands;}/*** 添加品牌* param brand*/public void add(Brand brand){//2 获取SqlSession对象执行SQL语句//2.1 获取SqlSession对象SqlSession sqlSession sqlSessionFactory.openSession();//2.2 获取Mapper接口UserMapper的代理对象BrandMapper brandMapper sqlSession.getMapper(BrandMapper.class);//2.3 执行添加品牌的sql语句brandMapper.add(brand);//3 注意增删改的SQL语句需要手动提交事务让其生效sqlSession.commit();//释放资源sqlSession.close();}/*** 修改——回显数据根据id查询* param id* return*/public Brand selectById(int id){//2 获取SqlSession对象执行SQL语句//2.1 获取SqlSession对象SqlSession sqlSession sqlSessionFactory.openSession();//2.2 获取Mapper接口UserMapper的代理对象BrandMapper brandMapper sqlSession.getMapper(BrandMapper.class);//2.3 执行修改——回显数据的sql语句Brand brand brandMapper.selectById(id);//释放资源sqlSession.close();return brand;}/*** 修改——修改数据* param brand*/public void update(Brand brand) {//2 获取SqlSession对象执行SQL语句//2.1 获取SqlSession对象SqlSession sqlSession sqlSessionFactory.openSession();//2.2 获取Mapper接口UserMapper的代理对象BrandMapper brandMapper sqlSession.getMapper(BrandMapper.class);//2.3 执行修改——修改数据的sql语句brandMapper.update(brand);//3 注意增删改的SQL语句需要手动提交事务让其生效sqlSession.commit();//释放资源sqlSession.close();}
}Web层 Step1修改在回显数据内容中的update.jsp代码如下 注意由于是通过id进行品牌数据的修改所以需要将id提交到服务端 %--Created by IntelliJ IDEA.User: 10195Date: 2024/6/30Time: 16:49To change this template use File | Settings | File Templates.
--%
% taglib prefixc urihttp://java.sun.com/jsp/jstl/core %
% page contentTypetext/html;charsetUTF-8 languagejava isELIgnoredfalse %
htmlheadtitle修改品牌/title/headbodyh3修改品牌/h3!--action的属性值为浏览器提交到服务器的资源路径--form action/BrandDemo/updateServlet methodpost%--通过隐藏域提交id作用隐藏id的提交--%input typehidden nameid value${brand.id}品牌名称input namebrandName value${brand.brandName}br企业名称input namecompanyName value${brand.companyName}br排序input nameordered value${brand.ordered}br描述信息textarea rows5 cols20 namedescription${brand.description}/textareabr状态c:choosec:when test${brand.status 0}input typeradio namestatus value0 checked禁用input typeradio namestatus value1启用br/c:whenc:otherwiseinput typeradio namestatus value0禁用input typeradio namestatus value1 checked启用br/c:otherwise/c:chooseinput typesubmit value提交/form/body
/htmlStep2通过JavaScript代码来为brand.jsp中的修改按钮添加鼠标单击事件 可详见前端知识点汇总单击修改按钮后页面会根据id跳转到对应品牌的页面即.jsp代码详见回显数据部分内容 Step3创建UpdateServlet类且代码如下 package at.guigu.web;import at.guigu.pojo.Brand;
import at.guigu.service.BrandService;import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;WebServlet(/updateServlet)
public class UpdateServlet extends HttpServlet {//1 创建一个私有的BrandService对象private BrandService brandService new BrandService();Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//添加数据时注意要处理中文乱码问题//处理post请求乱码request.setCharacterEncoding(UTF-8);//2 接收表单提交的修改数据并封装为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 new Brand();brand.setId(Integer.parseInt(id));brand.setBrandName(brandName);brand.setCompanyName(companyName);//将字符串数字先转换为Integer类型在存入Brand中brand.setOrdered(Integer.parseInt(ordered));brand.setDescription(description);brand.setStatus(Integer.parseInt(status));//3 调用brandService完成修改brandService.update(brand);//转发到查询所有的Servletrequest.getRequestDispatcher(/selectAllServlet).forward(request, response);}Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
}三层架构都准备完毕后Tomcat启动该Web项目Web项目启动成功后会默认运行index.html文件然后单击查询所有即可跳转到另一页面显示出查询数据之后单击修改按钮后会自动跳转到修改品牌页面修改完数据后单击提交按钮数据被提交到数据库保存然后页面会自动跳转到查询所有的页面显示出所有品牌数据如图所示