web(JSP、EL、JSTL、MVC)

JSP、EL、JSTL、MVC

JSP

JSP的优势

技术特点
HTML优:方便编写CSS和JS代码 缺:不能制作动态页面
Servlet优:可以制作动态页面 缺:不方便编写CSS和JS代码

JSP的概念

JSP的概念: Java Server Pages,Java服务器页面技术, 在服务器上编写动态和静态网页

JSP的作用

JSP=Servlet+HTML

既方便编写CSS和JS代码,同时又可以编写Java代码制作动态网页

JSP的示例

需求

在浏览器上输出服务器当前的时间,并且设置样式

运行效果

在这里插入图片描述

代码

<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>JSP</title>
    <style>
        h1 {
            border: 2px dashed red;
            background-color: yellow;
        }
    </style>
</head>
<body>
<h1>
   <%
       SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
       String format = sdf.format(new Date());
       out.print(format);
   %>
</h1>
</body>
</html>

JSP与Servlet之间的关系

JSP的执行过程

  1. JSP由Tomcat翻译成Java代码,而这个Java代码就是Servlet
  2. 将Servlet编译成字节码文件,由JVM来执行

JSP会被翻译成Servlet
在这里插入图片描述

疑问

  1. Servlet生成的位置

    找到idea启动时的log
    在这里插入图片描述
    在这里插入图片描述

  2. JSP和Servlet是什么关系?

    public final class JSP翻译类 extends org.apache.jasper.runtime.HttpJspBase
    
    再查看HttpJspBasepublic abstract class HttpJspBase extends HttpServlet 
    
    结论:JSP本质上就是一个Servlet
    
    原来的HTML,使用out.write()输出给浏览器
    原来的Java代码,原样不动的复制过去了
    
  3. JSP 什么时候翻译成 Servlet?生成多少次?

    浏览器第一次访问 JSP 的时候,由 Tomcat 将 JSP 翻译成了 Servlet,并且编译成字节码文件,只生成 1 次。
    如果这期间修改了 JSP 内容,就会重新生成
    

JSP的3种脚本元素

JSP代码片段

语法
<%
	Java代码;
%>
作用
可以编写Java, Java代码要符合Java语法
代码
<h1>JSP代码片段:</h1>
<%
    int a = 10;
    String str = "hello";
    ArrayList<String> list = new ArrayList<>();
    list.add("xxx");
    list.add("xxx");
    list.add("xxx");
    out.println(list);
%>

翻译后的代码

out.write("<h1>JSP代码片段:</h1>\r\n");

int a = 10;
String str = "hello";

ArrayList<String> list = new ArrayList<>();
list.add("xxx");
list.add("xxx");
list.add("xxx");
out.println(list);

JSP脚本表达式

语法
<%=变量名/表达式%>
作用
输出变量,做运算
代码演示
  1. 定义一个字符串输出
  2. 定义一个运算符输出
<h2>JSP表达式</h2>
<%
    int m=5;
%>
m的值: <%=m%> <br/>
计算表达式:<%=2*3%>
<hr/>
生成的Servlet代码
out.write("<h1>JSP脚本表达式:</h1>\r\n");

int m = 5;
out.write("\r\n");
out.write("m的值: ");
out.print(m);

out.write("\r\n");
out.write("<br/>\r\n");
out.write("计算表达式的值: ");
out.print(2*3);

JSP的声明

语法
<%!
    全局变量或方法
%>
作用
声明全局变量或方法,一般不会去生成方法
代码
<h1>JSP声明</h1>
<%!
    String name = "小明";
%>
<%
    String name = "小红";
%>

局部变量: <%=name%><br/>
成员变量: <%=this.name%>
生成的Servlet代码
out.write("<h1>JSP声明</h1>\r\n");
out.write('\r');
out.write('\n');

String name = "小明";

out.write("\r\n");
out.write("\r\n");
out.write("局部变量: ");
out.print(name);
out.write("<br/>\r\n");
out.write("成员变量: ");
out.print(this.name);

JSP的三大指令

三大指令是

  1. page
  2. taglib
  3. include

指令的格式

<%@指令名 属性名="属性值"%>

page指令

  1. 作用:设置网页上一些属性

  2. 语法:

    <%@page 属性名=属性值 %>
    

taglib指令

  1. 作用:用来导入JSTL中标签
  2. 语法:
<%@taglib prefix="前缀" uri="标签库标识"%>

include指令

  1. 作用:用于静态包含其它的页面

  2. 语法:

<%@include file="被包含的JSP页面"%>

include指令演示

代码
<div id="header">
    <%@include file="header.jsp"%>
</div>

JSP的page指令

page指令概述

  1. 作用:设置JSP网页中一些属性,告诉Web容器,将一个JSP页面翻译Servlet的参数。

  2. 位置:可以放在网页任何一个位置,但建议在网页最上面。

导包

方式一
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
每个import导入一个包
方式二
<%@ page import="java.util.Date,java.text.SimpleDateFormat" %>
一个import导入多个包,包之间使用逗号隔开

与编码相关的属性

contentType="text/html;charset=UTF-8"
JSP上汉字必须添加这个属性,否则汉字会有乱码的问题
相当于Servlet中response.setContentType("text/html;charset=UTF-8")

language="java"

与错误相关的属性

errorPage="错误页面的URL"  指定如果当前页面出错,跳转到哪个错误页面,转发另一个页面

<%@ page import="java.util.Date,java.text.SimpleDateFormat" %>
<%--相当于response.setContentType("text/html;charset=UTF-8");--%>
<%@ page contentType="text/html;charset=utf-8" language="java" errorPage="demo.jsp" %>
<html>
<head>
    <title>page指令的各种属性</title>
</head>
<body>
<%
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
    Date date = new Date();

    out.print(sdf.format(date));

    int m = 1 / 0;   //会出现500错误
%>
</body>
</html>
isErrorPage="true" 用在另一个处理错误的面上,指定当前这个JSP是一个错误处理页面

<%--这是一个错误页面,可以使用另一个内置对象:exception --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<img src="images/500.png">
</body>
</html>

错误页面的跳转的三种配置方式

方式一:errorPage
<%@ page contentType="text/html;charset=utf-8" language="java" errorPage="500.jsp" %>
方式二:错误码

在web.xml配置文件中指定错误码的方式

<error-page>
    <!--出现500错误-->
    <error-code>500</error-code>
    <!--location出错后跳转到哪一个页面-->
    <location>/500.jsp</location>
</error-page>

<error-page>
    <!--出现404错误-->
    <error-code>404</error-code>
    <!--location出错后跳转到哪一个页面-->
    <location>/404.jsp</location>
</error-page>
方式三:指定错误的类型

在web.xml配置文件中指定错误类型的方式

<error-page>
    <!--异常的类型,指定异常类全名-->
    <exception-type>java.lang.NullPointerException</exception-type>
    <!--location出错后跳转到哪一个页面-->
    <location>/404.jsp</location>
</error-page>
忽略el和session
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" session="true" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${3*5}
<br/>
<%=session%>
</body>
</html>

JSP的动作

三个动作

JSP的内置标签,可以直接使用。以jsp开头
在这里插入图片描述

include动作

  1. 作用:用来动态包含另一个JSP页面

  2. 语法:

    <jsp:include page="被包含页面"/>
    

include动作与指令的区别

静态包含动态包含
语法格式<%@include file=“URL”%><jsp:include page=“URL”/>
包含的方式包含的是内容,A包含B
先将B的文本内容复制到A中
再执行A页面
包含的是结果,A包含B
先执行B这个页面
再将B的执行结果包含在A中
生成Servlet个数只会生成一个Servlet会生成2个Servlet

注意:
如果2个页面中有相同的变量,不能使用静态包含,而应该使用动态包含。

forward和param动作

forward

  1. 功能:用于转发,相当于request.getRequestDispatcher("/URL").forward(request, response)
  2. 语法
<jsp:forward page="/页面地址"/>

param

  1. 功能:给forward和include提供参数名和值
  2. 语法:做为子标签存在
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>forward动作</title>
</head>
<body>
<%--转发动作,携带的参数,可以在demo上接收这2个参数--%>
<jsp:forward page="/demo.jsp">
    <jsp:param name="user" value="Jack"/>
    <jsp:param name="age" value="19"/>
</jsp:forward>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>转发到的页面</title>
</head>
<body>

<h2>demo转发到的页面</h2>
<%=request.getParameter("user")%> <br/>
<%=request.getParameter("age")%> <br/>
</body>
</html>

EL

EL的概念和作用

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>EL引入</title>
</head>
<body>
    <%
        request.setAttribute("n", 5);
    %>
    作用域的值:<%=request.getAttribute("n")%><br>
</body>
</html>

我们经常要往作用域中存放和取出数据,可以直接使用Java代码来进行,但是不是特别方便,通过EL可以方便的取出作用域中的数据

什么是EL

Expression Language 表达式语言

EL的作用

  1. 取出作用域中的值,并打印
  2. 用于进行各种运算:算术,逻辑,关系,三元运算等
区别JSP脚本表达式EL
语法<%=m%> 打印java的变量${m} 直接取出作用域中的数据进行打印
输出哪里的值输出的是脚本变量 <% int m= 10; %>输出的是作用域中的值 <% request.setAttribute(“m”, 5); %>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>EL引入</title>
</head>
<body>
    <%
        request.setAttribute("n", 5);
    %>
    作用域的值:<%=request.getAttribute("n")%><br>
    EL表达式:${n}<br>
    EL表达式:${n*3}
</body>
</html>

使用JSP和EL从四个作用域中取出数据

从指定的作用域中获取数据

什么是页面域
  • 对象名:pageContext,内置对象,可以直接在JSP上使用

  • 范围:在本JSP页面中有效

  • 作用域大小比较:pageContext < request < session < application(上下文)

  • 底层数据结构:上面四个作用域底层结构都是Map,存放键和值

pageContext页面域有关的方法

在这里插入图片描述

代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>使用JSP和EL从四个作用域中取出数据</title>
</head>
<body>
<%
    // 1.往作用域中存储数据
    pageContext.setAttribute("msg", "页面域的数据");
    request.setAttribute("msg", "请求域的数据");
    session.setAttribute("msg", "会话域的数据");
    application.setAttribute("msg", "上下文域的数据");
    // 4.删除四个域中同名的键
//    pageContext.removeAttribute("msg");
%>

<h2>2.使用JSP取出作用域的数据</h2>
<%=pageContext.getAttribute("msg")%><br/>
<%=request.getAttribute("msg")%><br/>
<%=session.getAttribute("msg")%><br/>
<%=application.getAttribute("msg")%><br/>
<h2>5.使用JSP自动查找作用域中的数据</h2>
<%=pageContext.findAttribute("msg")%>

<h2>3.使用EL取出作用域的数据</h2>
${pageScope.msg}<br/>
${requestScope.msg}<br/>
${sessionScope.msg}<br/>
${applicationScope.msg}<br/>
<h2>6.使用EL自动查找作用域中的数据</h2>
${msg}
</body>
</html>

使用EL取出不同数据类型的值

代码

public class Student {
    private int id;  //编号
    private String name;  //姓名
    private boolean gender;  //性别,true男 false女
    private double score;  //分数
}
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="com.xxx.entity.Student" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>取不同数据类型的值</title>
</head>
<body>
<h2>得到JavaBean中的属性值</h2>
<%
    Student student = new Student(100, "小明", true, 90);
    //放在页面域
    pageContext.setAttribute("stu", student);
%>
<%--本质上EL调用的是get方法,EL支持三元运算 --%>
姓名:${stu.name}  性别:${stu.gender?"男":'女'}
<hr>

<h2>得到List集合中的值</h2>
<%
    List<String> names = new ArrayList<>();
    names.add("小明");
    names.add("小红");
    names.add("小白");
    //放请求域
    pageContext.setAttribute("names", names);
%>
<%--通过索引号去取元素,EL不能遍历,如果要遍历元素,要使用JSTL --%>
第0个元素: ${names[0]}  第3个元素: ${names[3]}
<hr>

<h2>得到数组中的值</h2>
<%
    int [] arr = {100,30,54,18,21};
    pageContext.setAttribute("arr", arr);
%>
<%--通过数组的索引号去取--%>
${arr[2]}  ${arr[9]}
<hr>

<h2>得到Map中的值</h2>
<%
    Map<String, String> map = new HashMap<>();
    map.put("item1", "小明");
    map.put("item2", "小红");
    map.put("item3-4", "小白");
    pageContext.setAttribute("m",map);
%>
<%--如果键中包含了特殊的字符,使用如下格式--%>
${m.item1}  ${m["item3-4"]}
</body>
</html>

Map键名中有特殊字符的写法

${作用域变量名["键"]}

EL中各种运算符

算术运算符

算术运算符说明范例结果
+${1+1}2
-${2-1}1
*${1*1}1
/或div${5 div 2}2.5
%或mod取余${5 mod 2}1

比较运算符

关系运算符说明范例结果
== 或 eq等于(equal)${1 eq 1}true
!= 或 ne不等于(not equal)${1 != 1}false
< 或 lt小于(Less than)${1 lt 2}true
<= 或 le小于等于(Less than or equal)${1 <= 1}true
> 或 gt大于(Greater than)${1 > 2}false
>= 或 ge大于等于(Greater than or equal)${1 >= 1}true

逻辑运算符

逻辑运算符说明范例结果
&& 或 and交集(与)${true and false}false
|| 或 or并集(或)${true || false }true
! 或 not${not true}false

三元运算符

${条件表达式?真值:假值}

判空运算符

${empty 表达式}

代码

<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>EL中运算符</title>
</head>
<body>
<h2>算术运算符</h2>
${5 div 2} <br/>
${5 mod 2} <br/>

<h2>比较运算符</h2>
${1 eq 1} <br/>
${1 lt 2} <br/>

<h2>逻辑运算符</h2>
${true and false} <br/>

<h2>三元运算符</h2>
<%--param对象,相当于request.getParameter("age")--%>
${param.age>=18?"成年":"未成年"}

<h2>判空运算符</h2>
<%--
1. 判断指定的变量是否为空,如果为空,返回true
2. 判断指定的变量是否是空串,如果是空串,返回true
3. 如果变量是一个集合,判断这个集合中是否包含元素,如果没有,返回true
--%>

<%
    List<String> names = new ArrayList<>();
    names.add("小明");
    pageContext.setAttribute("names", names);
%>
${empty num} <br/>
${empty ""} <br/>
${empty names} <br/>
</body>
</html>

JSTL

JSTL的概念和作用

EL可以取出作用域中的数据进行打印。如果想做遍历,和判断等流程控制怎么办呢?

JSTL的概念

JSTL: Java Server Pages Standard Tag Library JSP标准标签库,JSTL就是一组自定义标签。直接使用这些标签,本质上还是运行Java代码。

JSTL标签可以将其分为以下5个类别:

  1. CORE 核心标签库:用于页面的流程控制。if for
  2. SQL标签库:在JSP页面上直接访问数据库
  3. XML标签库:在JSP页面上解析XML文件
  4. fmt标签库:用于国际化和格式化
  5. function标签库:16个字符串函数

HTML中标签

<br>
<input>

JSTL中标签

<c:if>
<c:forEach>

JSTL的标签:if标签

if标签作用

用于一个条件的判断

属性

属性名是否支持EL属性类型描述
test取值使用EL返回boolean类型如果EL中条件如果为真执行标签体内容,注:没有else
<c:if test="${param.age >= 18}">
    成年
</c:if>

JSTL的使用步骤

  1. 导包,复制到WEB-INF/lib
    在这里插入图片描述

  2. 创建JSP页面,在JSP页面上使用以下指令

    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    
  3. 在JSP页面上使用标签:

    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>JSP的if标签</title>
    </head>
    <body>
    
    </body>
    </html>
    

示例代码

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>if标签</title>
</head>
<body>
<c:if test="${param.age >= 18}">
    成年
</c:if>
</body>
</html>

JSTL的标签:choose标签

作用

用于2个以上的判断条件,多分支的语句

属性

标签名作用
choose一个容器,包含下面的2个标签。相当于java中swtich语句
when用于判断条件,有一个属性test指定判断条件,相当于case。when可以出现多个
otherwise如果上面所有的条件都不满足,执行这个内容。类似于switch中default
<c:choose>
    <c:when test="${param.age >= 18}">
        成年
    </c:when>
    <c:otherwise>
        未成年
    </c:otherwise>
</c:choose>
switch (表达式) {
	case1:
		语句体1;
		break;
	case2:
		语句体2;
		break;
	default :
		语句体n;
		break;
}

示例代码

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>JSTL的choose标签</title>
</head>
<body>
<h2>评级</h2>
<form action="demo.jsp" method="get">
    分数:
    <input type="text" name="score" value="${param.score}"/>
    <input type="submit" value="评级"/>
</form>

<%--相当于request.getParameter("score")--%>
<c:if test="${not empty param.score}">
    <c:choose>
        <c:when test="${param.score >= 80 and param.score <= 100}">
            优秀
        </c:when>
        <c:when test="${param.score >= 60 and param.score < 80}">
            及格
        </c:when>
        <c:when test="${param.score >= 0 and param.score < 60}">
            不及格
        </c:when>
        <c:otherwise>
            分数有误
        </c:otherwise>
    </c:choose>
</c:if>
</body>
</html>

JSTL的标签:forEach标签

forEach的作用

遍历集合或数组

Java的for循环:

for (int i = 0; i < 10; i++) {

}

JSTL的forEach循环:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>forEach</title>
</head>
<body>
<%--
从1到100
var:变量名,放在pageContext页面域中
begin: 开始值
end: 结束值
step: 步长
--%>
<c:forEach var="i" begin="1" end="100" step="2">
    ${i}
</c:forEach>
</body>
</html>

forEach属性

在这里插入图片描述

varStatus属性

在这里插入图片描述

示例代码

Student.java


/**
 * 学生对象
 */
public class Student {
    private int id;  //编号
    private String name;  //名字
    private boolean gender; //true男
    private double score;  //成绩
	// 省略getter/setter
}
JSP代码
<%@ page import="com.xxx.entity.Student" %>
<%@ page import="java.util.Arrays" %>
<%@ page import="java.util.List" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<!-- 网页使用的语言 -->
<html lang="zh-CN">
<head>
    <!-- 指定字符集 -->
    <meta charset="utf-8">
    <!-- 使用Edge最新的浏览器的渲染方式 -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。
    width: 默认宽度与设备的宽度相同
    initial-scale: 初始的缩放比,为1:1 -->
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>Bootstrap模板</title>

    <!-- 1. 导入CSS的全局样式 -->
    <link href="css/bootstrap.min.css" rel="stylesheet">
    <!-- 2. jQuery导入,建议使用1.9以上的版本 -->
    <script src="js/jquery-2.1.0.min.js"></script>
    <!-- 3. 导入bootstrap的js文件 -->
    <script src="js/bootstrap.min.js"></script>
    <style type="text/css">
        td, th {
            text-align: center;
        }
    </style>
</head>
<body>

<%
    List<Student> students = Arrays.asList(
            new Student(1000, "小明", true, 16),
            
    );

    // 2.放在请求域中
    pageContext.setAttribute("students", students);
%>
<div class="container">
    <h3 style="text-align: center">显示所有联系人</h3>
    <table border="1" class="table table-bordered table-hover">
        <tr class="success">
            <th>序号</th>
            <th>编号</th>
            <th>姓名</th>
            <th>性别</th>
            <th>年龄</th>
            <th>分数</th>
        </tr>

        <%--从请求域中取出数据,遍历得到每个学生对象,一个学生对象就是一行--%>
        <%--items: 要遍历的集合
        var="student": 遍历集合每次取出一个数据赋值给这个变量, 而且这个变量会保存到作用域中
            varStatus: 状态对象
                index: 遍历的索引
                count: 当前遍历出来的数量
                first: 是否是第一个元素,如果是返回true
                last: 是否是最后一个元素,如果是返回true
        --%>
        <c:forEach items="${students}" var="student" varStatus="mm">
            <tr>
                <td>${mm.last}</td>
                <td>${student.id}</td>
                <td>${student.name}</td>
                <td>${student.gender? "男" : '女'}</td>
                <td>${student.score}</td>
                <td><a class="btn btn-default btn-sm" href="修改联系人.html">修改</a>&nbsp;<a class="btn btn-default btn-sm" href="修改联系人.html">删除</a></td>
            </tr>
        </c:forEach>

        <tr>
            <td colspan="8" align="center"><a class="btn btn-primary" href="添加联系人.html">添加联系人</a></td>
        </tr>
    </table>
</div>
</body>
</html>

MVC

MVC介绍

概念

软件开发结构,与编程语言无关。

MVC全名是Model(模型),View(视图),Controller(控制器)

MVC是一种软件设计典范,将业务逻辑、数据存储、界面显示分离的方式来组织项目的代码。

组成说明JavaWeb中的实现
Model模型层业务层Service+数据访问层DAO+保存数据的对象JavaBean
View视图层展示数据给用户: JSP
Controller控制器MVC核心,接收用户是请求,使用Model得到数据,将Model的数据通过View展示给用户

Contrlloer通常是一个Servlet

流程图

在这里插入图片描述

JavaWeb中MVC实现

登录、查询余额、取款
在这里插入图片描述

访问流程说明

  1. 浏览器发送请求Servlet
  2. 由Servlet调用模型层得到数据
  3. 将返回的数据放在作用域中
  4. 转发到JSP页面上显示出来

案例第一步:项目结构的搭建、数据访问层、业务层

案例需求

使用三层架构和MVC模式开发代码,完成用户显示列表功能

案例分析

在这里插入图片描述

实现步骤

  1. 编写SQL语句
  2. 导入Jar包
  3. sqlMapConfig.xml配置文件
  4. 实体类
  5. MybatisUtils工具类
  6. 编写DAO代码
  7. 编写业务层代码

SQL语句

CREATE DATABASE test;
USE test;

CREATE TABLE contact( 
   id INT PRIMARY KEY AUTO_INCREMENT , 
   NAME VARCHAR(20) NOT NULL , 
   sex CHAR(1) , 
   age INT(3) UNSIGNED ,   -- 无符号
   address VARCHAR(10) ,   -- 籍贯
   qq VARCHAR(18) , 
   email VARCHAR(25) 
 ) ;
 
-- 插入记录
INSERT  INTO contact(NAME,sex,age,address,qq,email) VALUES 
('小明','男',25,'广东','834523234','xiaoming@xxx.com'),...

导入jar包

在这里插入图片描述

sqlMapConfig.xml配置文件

实体类

public class Contact {
    private int id;
    private String name;
    private String sex;
    private int age;
    private String address;
    private String qq;
    private String email;
	// 省略getter/setter
}

MybatisUtils工具类

public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory = null;
    // 初始化 SqlSessionFactory 对象
    static {
        try{
            // 1.读取配置文件
            String resource ="sqlMapConfig.xml";
            Reader reader = Resources.getResourceAsReader(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader );
        } catch(Exception e) {
            e.printStackTrace();
        }

    }
	
	// 获取 SqlSession 对象的静态方法
    public static SqlSession getSession() {
        return sqlSessionFactory.openSession();
    }
	
    // 获取 SqlSession 对象的静态方法
    public static SqlSession getSession(boolean isAutoCommit) {
        return sqlSessionFactory.openSession(isAutoCommit);
    }


    // 关闭sqlSession
    public static void closeSession(SqlSession sqlSession) {
        sqlSession.commit();
        sqlSession.close();
    }
}

编写DAO代码

public interface ContactMapper {
    // 查询联系人
    @Select("SELECT * FROM contact;")
    List<Contact> findAllContacts();
}

编写业务层代码

/**
 * 业务层
 */
public class ContactService {
    /**
     * 查询所有的联系人
     */
    public List<Contact> findAllContacts() {
        SqlSession sqlSession = MybatisUtils.getSession();
        ContactMapper mapper = sqlSession.getMapper(ContactMapper.class);
        List<Contact> allContacts = mapper.findAllContacts();

        return allContacts;
    }
}

案例第二步:查询所有联系人的Web层

Servlet代码

/**
 * 查询所有的联系人
 */
@WebServlet("/list")
public class ListContactServlet extends HttpServlet {

    private ContactService contactService = new ContactService();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.调用业务层得到所有的联系人
        List<Contact> contacts = contactService.findAllContacts();

        // 2.将联系人集合放在请求域中
        request.setAttribute("contacts", contacts);

        // 3.转发到JSP,显示出来
        request.getRequestDispatcher("/list.jsp").forward(request, response);
    }

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

导入联系人页面素材

复制"原型/联系人"下的"css",“fonts”,"js"三个文件夹和"list.jsp"到web根路径

修改list.jsp页面显示联系人

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<!-- 网页使用的语言 -->
<html lang="zh-CN">
<head>
    <!-- 指定字符集 -->
    <meta charset="utf-8">
    <!-- 使用Edge最新的浏览器的渲染方式 -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。
    width: 默认宽度与设备的宽度相同
    initial-scale: 初始的缩放比,为1:1 -->
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>显示所有联系人</title>

    <!-- 1. 导入CSS的全局样式 -->
    <link href="css/bootstrap.min.css" rel="stylesheet">
    <!-- 2. jQuery导入,建议使用1.9以上的版本 -->
    <script src="js/jquery-2.1.0.min.js"></script>
    <!-- 3. 导入bootstrap的js文件 -->
    <script src="js/bootstrap.min.js"></script>
    <style type="text/css">
        td, th {
            text-align: center;
        }
    </style>
</head>
<body>
<div class="container">
    <h3 style="text-align: center">显示所有联系人</h3>
    <table border="1" class="table table-bordered table-hover">
        <tr class="success">
            <th>编号</th>
            <th>姓名</th>
            <th>性别</th>
            <th>年龄</th>
            <th>籍贯</th>
            <th>QQ</th>
            <th>邮箱</th>
            <th>操作</th>
        </tr>
        <c:forEach items="${contacts}" var="contact">
            <tr>
                <td>${contact.id}</td>
                <td>${contact.name}</td>
                <td>${contact.sex}</td>
                <td>${contact.address}</td>
                <td>${contact.address}</td>
                <td>${contact.qq}</td>
                <td>${contact.email}</td>
                <td><a class="btn btn-default btn-sm" href="修改联系人.html">修改</a>&nbsp;<a class="btn btn-default btn-sm" href="修改联系人.html">删除</a></td>
            </tr>
        </c:forEach>
        <tr>
            <td colspan="8" align="center"><a class="btn btn-primary" href="添加联系人.html">添加联系人</a></td>
        </tr>
    </table>
</div>
</body>
</html>

案例第三步:删除用户

DAO的代码

public interface ContactMapper {
    // 查询联系人
    @Select("SELECT * FROM contact;")
    List<Contact> findAllContacts();

    // 删除联系人
    @Delete("DELETE FROM contact WHERE id=#{id};")
    int deleteContact(int id);
}

Service层

/**
 * 业务层
 */
public class ContactService {

    private ContactDao contactDao = new ContactDaoImpl();

    /**
     * 查询所有的联系人
     */
    public List<Contact> findAllContacts() {
        return contactDao.findAllContacts();
    }

    /**
     * 删除联系人
     */
    public int deleteContact(int id) {
        return contactDao.deleteContact(id);
    }
}

DeleteServlet

@WebServlet(name = "DeleteContactServlet", urlPatterns = "/delete")
public class DeleteContactServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.得到需要删除的id
        String id = request.getParameter("id");

        // 2.调用业务层删除联系人
        if (id != null) {
            ContactService service = new ContactService();
            service.deleteContact(Integer.parseInt(id));

            // 3.删除以后重定向到/list
            response.sendRedirect(request.getContextPath() + "/list");
        }
    }
}

修改list.jsp处理删除按钮点击

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<!-- 网页使用的语言 -->
<html lang="zh-CN">
<head>
    <!-- 指定字符集 -->
    <meta charset="utf-8">
    <!-- 使用Edge最新的浏览器的渲染方式 -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。
    width: 默认宽度与设备的宽度相同
    initial-scale: 初始的缩放比,为1:1 -->
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>Bootstrap模板</title>

    <!-- 1. 导入CSS的全局样式 -->
    <link href="css/bootstrap.min.css" rel="stylesheet">
    <!-- 2. jQuery导入,建议使用1.9以上的版本 -->
    <script src="js/jquery-2.1.0.min.js"></script>
    <!-- 3. 导入bootstrap的js文件 -->
    <script src="js/bootstrap.min.js"></script>
    <style type="text/css">
        td, th {
            text-align: center;
        }
    </style>
</head>
<body>
<div class="container">
    <h3 style="text-align: center">显示所有联系人</h3>
    <table border="1" class="table table-bordered table-hover">
        <tr class="success">
            <th>编号</th>
            <th>姓名</th>
            <th>性别</th>
            <th>年龄</th>
            <th>籍贯</th>
            <th>QQ</th>
            <th>邮箱</th>
            <th>操作</th>
        </tr>

        <%--取出request请求域中的数据,遍历将每个联系人都显示成一行--%>
        <c:forEach items="${contacts}" var="contact">
            <tr>
                <td>${contact.id}</td>
                <td>${contact.name}</td>
                <td>${contact.sex? "男": "女"}</td>
                <td>${contact.age}</td>
                <td>${contact.address}</td>
                <td>${contact.qq}</td>
                <td>${contact.email}</td>
                <td><a class="btn btn-default btn-sm" href="修改联系人.html">修改</a>&nbsp;<a class="btn btn-default btn-sm" οnclick="deleteContact(${contact.id})">删除</a></td>
            </tr>
        </c:forEach>

        <tr>
            <td colspan="8" align="center"><a class="btn btn-primary" href="添加联系人.html">添加联系人</a></td>
        </tr>
    </table>
    
    <script>
        function deleteContact(id) {
            // alert(id);
            if (confirm("您真的要删除id为" + id + "这条数据吗?")) {
                // 让浏览器转到这个删除Servlet,去删除数据 http://localhost:8080/xxx/delete?id=
                location.href = "delete?id=" + id;
            }
        }
    </script>
</div>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值