WEB阶段7:综合练习-联系人管理系统-增删改查&查询分页

  • Post author:
  • Post category:其他




综合练习-联系人管理系统-增删改查&查询分页



回顾

  1. 能够说出过滤器的作用

    1. 解决全局乱码问题
    2. 用户权限访问控制
    3. 用户输入文本内容进行过滤
  2. 能够编写过滤器

    1. 创建一个类实现javax.servlet.Filter接口
    2. 重写接口中方法,其中doFilter()进行过滤
    3. 在web.xml中配置或@WebFilter注解

    什么时候作用xml配置,什么时候使用注解?

    我们自己写的过滤器,建议使用注解。如果引用第三方的过滤器,使用XML配置。
    
  3. 能够说出过滤器生命周期相关方法

    Filter接口中的方法 作用和执行次数
    void init(FilterConfig filterConfig) 服务器启动的时候执行1次
    void doFilter(ServletRequest request,

    ServletResponse response, FilterChain chain)
    每次执行过滤器的时候都会执行
    public void destroy() 服务器关闭执行1次
  4. 能够根据过滤路径判断指定的过滤器是否起作用

    匹配方式 匹配哪些资源
    以/开头 精确匹配:/demo1 访问地址与过滤地址完全一样
    目录匹配:/目录名/* 过滤指定目录下所有的资源
    过滤所有的资源: /*
    以扩展名结尾 *.扩展名 过滤指定类型的文件

    /开头和扩展名结尾不能同时出现在一个路径中
  5. 能够说出什么是过滤器链

    1. XML:按web.xml中配置的先后顺序
    2. 注解:按类名的字母顺序排序,哪个在前面哪个就先执行

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MJNbBm7v-1599221050427)(assets/1552919236666.png)]

  6. 能够编写过滤器解决全局乱码

    1. 判断是否是POST方法
    2. 如果是,使用request.setCharacterEncoding()

    注:过滤器中请求和响应接口是父接口,如果要使用子接口的方法,必须要进行向下转型。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nhsgh50Y-1599221050430)(assets/1552918911663.png)]

  7. 能够说出监听器的作用

    1. 监听作用域中创建和销毁
    2. 监听作用域中属性的增删改操作
  8. 能够使用ServletContextListener监听器

    监听上下文域创建和销毁

    1. 监听创建
    2. 监听销毁



学习目标

  1. 能够理解添加记录的功能
  2. 能够理解删除多条记录的功能
  3. 能够理解更新记录的功能
  4. 能够理解分页查询所有记录的功能



学习内容



1. 查询联系人:编写数据访问层和业务层



目标

  1. 搭建MVC和三层架构
  2. 编写数据访问层和业务层



案例需求

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



案例效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i8haKBfM-1599221050449)(assets/image-20200904161954800.png)]



SQL语句

CREATE DATABASE day32;

USE day32;

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','zhuzhuxia@itcast.cn'),
('貂蝉','女',18,'湖南','59869834','diaochan@qq.com'),
('孙悟空','男',28,'湖南','87967822','wukong@itheima.com'),
('周瑜','男',25,'广西','2743759345','zhou@163.com');

SELECT * FROM contact;



导入jar包

image-20200904084808036



mybatis核心配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <settings>
        <!--在控制台显示SQL语句-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

    <!--定义实体类别名-->
    <typeAliases>
        <package name="com.itheima.entity"/>
    </typeAliases>

    <environments default="default">
        <!--环境变量-->
        <environment id="default">
            <!--事务管理器-->
            <transactionManager type="JDBC"/>
            <!--数据源-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/day32"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <!--加载其它映射文件-->
    <mappers>
        <package name="com.itheima.dao"/>
    </mappers>
</configuration>



实体类

package com.itheima.entity;

public class Contact {

    private int id;
    private String name;
    private String sex;
    private int age;
    private String address;
    private String qq;
    private String email;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getQq() {
        return qq;
    }

    public void setQq(String qq) {
        this.qq = qq;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "Contact{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                ", qq='" + qq + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}



会话工具类

package com.itheima.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

/**
 * 会话工具类
 */
public class SqlSessionUtils {

    //会话工厂的创建类->会话工厂->会话
    private static SqlSessionFactory factory;

    static {
        //1.会话工厂的创建类
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //2.得到配置文件的输入流
        try (InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml")) {
            //3.创建会话工厂
            factory = builder.build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 得到会话对象
     * @return
     */
    public static SqlSession getSession() {
        return factory.openSession();
    }


}



编写DAO代码

package com.itheima.dao;

import com.itheima.entity.Contact;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
 * DAO的接口
 */
public interface ContactDao {

    /**
     * 查询所有的联系人
     */
    @Select("SELECT * FROM contact")
    List<Contact> findAll();
}
package com.itheima.dao.impl;

import com.itheima.dao.ContactDao;
import com.itheima.entity.Contact;
import com.itheima.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;

import java.util.List;

public class ContactDaoImpl implements ContactDao {
    @Override
    public List<Contact> findAll() {
        //1.获取会话对象
        SqlSession session = SqlSessionUtils.getSession();
        //2.创建DAO接口的代理对象
        ContactDao contactDao = session.getMapper(ContactDao.class);
        //3.调用接口的方法
        List<Contact> contacts = contactDao.findAll();
        //4.关闭会话
        session.close();
        //5.返回值
        return contacts;
    }
}



编写业务层代码

package com.itheima.service;

import com.itheima.entity.Contact;

import java.util.List;

/**
 * 业务层接口
 */
public interface ContactService {

    /**
     * 查询所有的联系人
     */
    List<Contact> findAll();

}

package com.itheima.service.impl;

import com.itheima.dao.ContactDao;
import com.itheima.dao.impl.ContactDaoImpl;
import com.itheima.entity.Contact;
import com.itheima.service.ContactService;

import java.util.List;

public class ContactServiceImpl implements ContactService {

    //业务层依赖于dao
    private ContactDao contactDao = new ContactDaoImpl();

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



小结

  1. 搭建环境
  2. 导包
  3. 创建dao接口和实现类
  4. 创建业务接口和实现类



2. 查询联系人:Web层



目标

  1. 使用Servlet来调用业务层,得到所有的联系人

  2. 在JSP上使用JSTL显示请求域中数据



效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rao9k4nz-1599221050523)(assets/image-20200904162000954.png)]



步骤



Servlet代码

package com.itheima.servlet;

import com.itheima.entity.Contact;
import com.itheima.service.ContactService;
import com.itheima.service.impl.ContactServiceImpl;

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

@WebServlet("/list")
public class ListContactServlet extends HttpServlet {

    //业务层
    private ContactService contactService = new ContactServiceImpl();
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.调用业务层获取所有的联系人
        List<Contact> contacts = contactService.findAll();
        //2.把集合放在请求域
        request.setAttribute("contacts", contacts);
        //3.转发到list.jsp页面
        request.getRequestDispatcher("/list.jsp").forward(request, response);
    }

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



导入Bootstrap页面的文件夹

复制”原型”下的所有内容到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">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <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">
        tr, th {
            text-align: center;
        }
    </style>
</head>
<body>
<div class="container">
    <h2 class="text-center">联系人列表</h2>
    <form action="list" method="get" class="form-inline" id="contactForm">
        <div class="row text-right" style="margin-bottom: 10px; margin-top: 15px;">
            <div class="col-md-4 text-left">
                <a class="btn btn-primary" style="width: 120px" href="add.jsp">添加联系人</a>
            </div>
        </div>

        <div class="row">
            <div class="col-md-12">
                <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>
                    <%--
                    items:要遍历的集合
                    var:每次遍历的元素,它是一个变量名,放在页面域中
                    一开始应该访问/list这个Servlet
                    --%>
                    <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>
							<div class="btn-group btn-group-sm">
								<a class="btn btn-success btn-xs" href="#">修改</a>&nbsp;
								<a class="btn btn-info btn-xs" href="#">删除</a>
							</div>
						</td>
					</tr>
                    </c:forEach>
                </table>
            </div>
        </div>

        <div class="row text-center">
            <div class="btn-group btn-group-sm">
					<a href="#" class="btn btn-default">首页</a>
					<a href="#" class="btn btn-default">上页</a>
					<a href="#" class="btn btn-default">下页</a>
					<a href="#" class="btn btn-default">末页</a>
            </div>

            每页
            <input type="number" class="form-control" name="size" style="width: 60px;" id="size"/>
            条

            第
            <select id="current" class="form-control" name="current">
               <option value="1">1</option>
            </select>
            页/共5页  共30条
        </div>
    </form>
</div>

</div>
</body>
<script type="text/javascript">
</script>

</html>

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>首页</title>
  </head>
  <body>
  <%--一开始转发到servlet中去--%>
  <jsp:forward page="/list"></jsp:forward>
  </body>
</html>



3. 添加联系人:DAO层和业务层



目标

实现联系人的添加



序列图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K5w1OU91-1599221050526)(assets/image-20200904090921640.png)]



DAO层

/**
 * 添加1个联系人
 */
@Insert("INSERT INTO contact VALUES (NULL,#{name},#{sex},#{age},#{address},#{qq},#{email})")
int addContact(Contact contact);
/**
 * 添加1个联系人
 * 必须要提交事务
 * @param contact
 */
@Override
public int addContact(Contact contact) {
    //1.获取会话对象
    SqlSession session = SqlSessionUtils.getSession();
    //2.创建DAO接口的代理对象
    ContactDao contactDao = session.getMapper(ContactDao.class);
    //3.调用接口的方法
    int row = contactDao.addContact(contact);  //返回影响的行数
    //3.5 提交事务 
    session.commit();
    //4.关闭会话
    session.close();
    //5.返回值
    return row;
}



业务层

package com.itheima.service.impl;

import com.itheima.dao.ContactDao;
import com.itheima.dao.impl.ContactDaoImpl;
import com.itheima.entity.Contact;
import com.itheima.service.ContactService;

import java.util.List;

public class ContactServiceImpl implements ContactService {

    //业务层依赖于dao
    private ContactDao contactDao = new ContactDaoImpl();

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

    /**
     * 添加联系人
     * @param contact
     */
    @Override
    public int addContact(Contact contact) {
        return contactDao.addContact(contact);
    }
}



4. 添加联系人:Web层



目标

  1. 编码的过滤器
  2. Servlet



编码过滤器

package com.itheima.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter(filterName = "CharacterEncodingFilter", urlPatterns = "/*")
public class CharacterEncodingFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //设置编码
        req.setCharacterEncoding("utf-8");
        //放行
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {

    }

}



Servlet

package com.itheima.servlet;

import com.itheima.entity.Contact;
import com.itheima.service.ContactService;
import com.itheima.service.impl.ContactServiceImpl;
import org.apache.commons.beanutils.BeanUtils;

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.lang.reflect.InvocationTargetException;
import java.util.Map;

@WebServlet("/add")
public class AddContactServlet extends HttpServlet {

    private ContactService contactService = new ContactServiceImpl();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取所有的表单数据
        Map<String, String[]> map = request.getParameterMap();
        //2.封装成Contact对象
        Contact contact = new Contact();
        try {
            //把map对象复制到contact属性中
            BeanUtils.populate(contact, map);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //3.调用业务层添加
        contactService.addContact(contact);
        //4.添加成功以后重定向/list
        response.sendRedirect(request.getContextPath() + "/list");
    }

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



小结

添加联系人的注意事项:

  1. 汉字要处理乱码的问题,使用过滤器处理
  2. 给contact对象设置属性,使用BeanUtils工具类



5. 制作通用的DAO实现类



目标

制作通用的DAO实现类



回顾动态代理



动态代理的好处

  1. 代理对象由程序在执行的过程中动态生成,不用我们自己去写一个类实现接口中所有的方法
  2. 可以动态生成任意接口的对象



Proxy类中的方法

我们自己写的所有的类都使用的是同一个类加载器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-860DV6om-1599221050529)(assets/1557839380147.png)]



InvocationHandler接口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MZo14QBd-1599221050531)(assets/1557839397638.png)]



步骤

  1. 创建类:DaoInstanceFactory,使用动态代理创建DAO的实现类
  2. 创建静态方法得到DAO的实现类,方法签名:
public static <T> T getBean(Class<T> daoInterface)
  1. 在每个被代理的方法中

    1. 得到会话对象
    2. 通过会话得到Mapper对象
    3. 调用原来DAO接口中的方法
    4. 提交事务
    5. 关闭会话
    6. 返回原来方法的值



代码

package com.itheima.utils;

import com.itheima.dao.ContactDao;
import com.itheima.entity.Contact;
import org.apache.ibatis.session.SqlSession;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

public class DaoInstanceFactory {

/**
 * 生成DAO接口的代理对象
 * @param daoInterfaceType 要代理的接口类型,如:ContactDao.class
 */
public static <T> T getBean(Class<T> daoInterfaceType) {
	/*
	参数1:类加载器,只要我们写的类使用的是同一个类加载器
	参数2:接口数组,所有要实现的接口
	参数3:回调函数,接口中每个被代理的方法都会调用一次
	 */
	return (T) Proxy.newProxyInstance(
			DaoInstanceFactory.class.getClassLoader(),
			new Class[]{daoInterfaceType},
			new InvocationHandler() {
				/**
				 * 接口中每个被代理的方法都会调用一次
				 * @param proxy 代理对象
				 * @param method 每个被代理的方法
				 * @param args 方法的参数
				 * @return 方法的返回值
				 */
				@Override
				public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
					//1.获取会话对象
					SqlSession session = SqlSessionUtils.getSession();
					//2.创建DAO接口的代理对象
					T obj = session.getMapper(daoInterfaceType);
					System.out.println("调用DAO的方法:" + method.getName() + ",参数是:" + Arrays.toString(args));
					//3.调用接口的方法,参数1:实例对象,参数2:参数数组
					Object result = method.invoke(obj, args);
					//4 提交事务
					session.commit();
					//5.关闭会话
					session.close();
					//6.返回值
					return result;
				}
			} );
	}
}



业务层代码修改

private ContactDao contactDao = DaoInstanceFactory.getBean(ContactDao.class);



6. 修改联系人:数据回显



目标

1563196032972



序列图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vA2Dkr8i-1599221050534)(assets/image-20200904103238573.png)]



代码

DAO

/**
 * 通过id查询一个联系人
 */
@Select("SELECT * FROM contact WHERE id=#{id}")
Contact findById(int id);

Service

/**
 * 通过id查询联系人
 * @param id
 */
@Override
public Contact findById(int id) {
    return contactDao.findById(id);
}

Servlet

package com.itheima.servlet;

import com.itheima.entity.Contact;
import com.itheima.service.ContactService;
import com.itheima.service.impl.ContactServiceImpl;

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;

/**
 * 通过id查询1个联系人
 */
@WebServlet("/query")
public class QueryContactServlet extends HttpServlet {

    private ContactService contactService = new ContactServiceImpl();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取id的值
        String id = request.getParameter("id");
        //2.调用业务层获取一个联系人对象
        Contact contact = contactService.findById(Integer.parseInt(id));
        //3.将联系人放在请求域中
        request.setAttribute("contact", contact);
        //4.转发到update.jsp显示
        request.getRequestDispatcher("/update.jsp").forward(request, response);
    }

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



7. 修改联系人:显示数据的表示层



目标

  1. list.jsp链接的修改

  2. 更新页面的数据回显



代码

list.jsp

点修改按钮以后跳转到QueryContactServlet,并且传递id的值

<%--query是通过id查询一条记录的servlet--%>
<a class="btn btn-success btn-xs" href="query?id=${contact.id}">修改</a>&nbsp;

Servlet的变化:把城市放在请求域中

package com.itheima.servlet;

import com.itheima.entity.Contact;
import com.itheima.service.ContactService;
import com.itheima.service.impl.ContactServiceImpl;

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;

/**
 * 通过id查询1个联系人
 */
@WebServlet("/query")
public class QueryContactServlet extends HttpServlet {

    private ContactService contactService = new ContactServiceImpl();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取id的值
        String id = request.getParameter("id");
        //2.调用业务层获取一个联系人对象
        Contact contact = contactService.findById(Integer.parseInt(id));
        //3.将联系人放在请求域中
        request.setAttribute("contact", contact);
        //把城市放在请求域中
        request.setAttribute("cities", new String[] {"广东","广西","湖南","湖北","海南"});
        //4.转发到update.jsp显示
        request.getRequestDispatcher("/update.jsp").forward(request, response);
    }

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

update.jsp

把所有的属性从请求域中取出并且显示在页面上

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<!-- 网页使用的语言 -->
<html lang="zh-CN">
<head>
    <!-- 指定字符集 -->
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>修改用户</title>

    <link href="css/bootstrap.min.css" rel="stylesheet">
    <script src="js/jquery-2.1.0.min.js"></script>
    <script src="js/bootstrap.min.js"></script>

</head>
<body>
<div class="container" style="width: 400px;">
    <h3 style="text-align: center;">修改联系人</h3>
    <form action="update" method="post">
        <div class="form-group">
            <label for="name">姓名:</label>
            <%--readonly="readonly" 表示只读,不能修改. placeholder="请输入姓名" 提示信息 --%>
            <input type="text" class="form-control" id="name" name="name" placeholder="请输入姓名" value="${contact.name}"/>
        </div>

        <div class="form-group">
            <label>性别:</label>
            <%--选中某一项:checked="checked", 判断性别的值如果等于男,选中男--%>
            <input type="radio" name="sex" value="男" ${contact.sex=='男'?'checked="checked"':''}/>男
            <input type="radio" name="sex" value="女" ${contact.sex=='女'?'checked="checked"':''}/>女
        </div>

        <div class="form-group">
            <label for="age">年龄:</label>
            <input type="number" class="form-control" id="age" name="age" placeholder="请输入年龄" value="${contact.age}"/>
        </div>

        <div class="form-group">
            <label for="address">籍贯:</label>
            <select name="address" class="form-control" id="address">
                <%--所有的选项从数组中获取--%>
                <c:forEach items="${cities}" var="city">
                    <%--如果联系人的地址与遍历的地址相同,就选中--%>
                    <option value="${city}" ${contact.address==city?'selected="selected"':''}>${city}</option>
                </c:forEach>
            </select>
        </div>

        <div class="form-group">
            <label for="qq">QQ:</label>
            <input type="number" class="form-control" name="qq" placeholder="请输入QQ号码" id="qq" value="${contact.qq}"/>
        </div>

        <div class="form-group">
            <label for="email">Email:</label>
            <input type="text" class="form-control" name="email" placeholder="请输入邮箱地址" id="email" value="${contact.email}"/>
        </div>

        <div class="form-group" style="text-align: center">
            <input class="btn btn-primary" type="submit" value="提交"/>
            <input class="btn btn-default" type="reset" value="重置"/>
            <input class="btn btn-default" type="button" value="返回" οnclick="history.back()"/>
        </div>
    </form>
</div>
</body>
</html>



小结

页面上显示的数据有以下几种:

  1. 单选框:checked=“checked”
  2. 下拉列表:selected=“selected”
  3. 文本框:value=“值”



8. 修改联系人:更新操作



目标

将用户修改后的信息写入数据库



序列图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oOFzrOq6-1599221050536)(assets/image-20200904105849618.png)]



代码

DAO

/**
 * 更新联系人
 */
@Update("UPDATE contact SET NAME = #{name},sex = #{sex},age = #{age},address = #{address},qq = #{qq},email = #{email} WHERE id = #{id}")
int updateContact(Contact contact);

Service

/**
 * 更新联系人
 * @param contact
 */
@Override
public int updateContact(Contact contact) {
    return contactDao.updateContact(contact);
}

Servlet

package com.itheima.servlet;

import com.itheima.entity.Contact;
import com.itheima.service.ContactService;
import com.itheima.service.impl.ContactServiceImpl;
import org.apache.commons.beanutils.BeanUtils;

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.lang.reflect.InvocationTargetException;
import java.util.Map;

/**
 * 与表单的action名字一样
 */
@WebServlet("/update")
public class UpdateContactServlet extends HttpServlet {

    private ContactService contactService = new ContactServiceImpl();
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取表单提交的所有参数值
        Map<String, String[]> map = request.getParameterMap();
        //2.封装成Contact对象
        Contact contact = new Contact();
        try {
            BeanUtils.populate(contact,map);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //3.调用业务层更新联系人
        contactService.updateContact(contact);
        //4.重定向到/list
        response.sendRedirect(request.getContextPath() + "/list");
    }

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

update.jsp

<%--id是给程序员用的,不需要用户看到,使用隐藏域,页面上看不到,但可以把值提交到服务器--%>
<input type="hidden" name="id" value="${contact.id}">



9. 通过ID删除联系人



目标

  1. 实现联系人的删除
  2. 删除前有确认



序列图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2Rkl5Cnf-1599221050537)(assets/image-20200904111317816.png)]



DAO层

/**
 * 通过id删除一条记录
 */
@Delete("delete from contact where id=#{id}")
int deleteContact(int id);



业务层

/**
 * 通过id删除一条记录
 * @param id
 */
@Override
public int deleteContact(int id) {
    return contactDao.deleteContact(id);
}



Servlet

package com.itheima.servlet;

import com.itheima.service.ContactService;
import com.itheima.service.impl.ContactServiceImpl;

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;

/**
 * 通过id删除联系人
 */
@WebServlet("/delete")
public class DeleteContactServlet extends HttpServlet {

    private ContactService contactService = new ContactServiceImpl();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取id
        String id = request.getParameter("id");
        //2.调用业务层删除联系人
        contactService.deleteContact(Integer.parseInt(id));
        //3.重定向到/list
        response.sendRedirect(request.getContextPath() + "/list");
    }

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



list.jsp

  1. 添加varStatus属性,修改了它编号
  2. 删除按钮上使用href=“javascript:函数(id, name)”
  3. 写script代码,删除前进行确认
<%@ 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">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<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">
	tr, th {
		text-align: center;
	}
</style>
</head>
<body>
<div class="container">
<h2 class="text-center">联系人列表</h2>
<form action="list" method="get" class="form-inline" id="contactForm">
	<div class="row text-right" style="margin-bottom: 10px; margin-top: 15px;">
		<div class="col-md-4 text-left">
			<a class="btn btn-primary" style="width: 120px" href="add.jsp">添加联系人</a>
		</div>
	</div>

	<div class="row">
		<div class="col-md-12">
			<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>
				<%--
				items:要遍历的集合
				var:每次遍历的元素,它是一个变量名,放在页面域中
				varStauts:状态对象,四个属性:index,count,first,last
				一开始应该访问/list这个Servlet

				--%>
				<c:forEach items="${contacts}" var="contact" varStatus="row">
					<tr>
						<td>${row.count}</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>
							<div class="btn-group btn-group-sm">
									<%--query是通过id查询一条记录的servlet--%>
								<a class="btn btn-success btn-xs" href="query?id=${contact.id}">修改</a>&nbsp;
									<%--href中写javascript:表示,点这个链接调用一个JS代码--%>
								<a class="btn btn-info btn-xs" href="javascript:deleteContact('${contact.id}','${contact.name}')">删除</a>
							</div>
						</td>
					</tr>
				</c:forEach>
			</table>
		</div>
	</div>

	<div class="row text-center">
		<div class="btn-group btn-group-sm">
			<a href="#" class="btn btn-default">首页</a>
			<a href="#" class="btn btn-default">上页</a>
			<a href="#" class="btn btn-default">下页</a>
			<a href="#" class="btn btn-default">末页</a>
		</div>

		每页
		<input type="number" class="form-control" name="size" style="width: 60px;" id="size"/>
		条

		第
		<select id="current" class="form-control" name="current">
			<option value="1">1</option>
		</select>
		页/共5页 共30条
	</div>
</form>
</div>

</div>
</body>
<script type="text/javascript">
//删除联系人前要进行确认, id就是要删除的主键
function deleteContact(id, name) {
	if (confirm("真的要删除" + name + "这条记录吗?")) {
		//跳转到servlet中
		location.href = "delete?id=" + id;
	}
}
</script>

</html>



10. 分页对象:PageBean分析



目标

设计分页对象PageBean的8个属性



准备数据

-- 插入记录
insert  into contact(name,sex,age,address,qq,email)  values 
('陈宏子','男',21,'广东','15811688','cheng@126.com'),
 ('秦婷婷','女',25,'广东','15888802','zhangsan1@126.com'),
 ('折蓉蓉','女',30,'广东','13423333','zherong@163.com'),
 ('曹丽娜','女',26,'广东','12223333','zhangsan1@qq.com'),
 ('李娜','女',46,'广西','1343333','zhangsan1@itcast.cn'),
 ('姜钰','男',49,'湖南','13223333','zhangsan1@qq.com'),
 ('魏天霞','女',38,'湖南','13054863','zhangsan1@126.com'),
 ('王官君','男',22,'湖南','1422233','zhangsan1@126.com'),
 ('王红梅','女',25,'福建','2777726','wang@qq.com'),
 ('郭淑慧','女',28,'海南','6058168','guoshu@qq.com'),
 ('马海娟','女',29,'海南','13829882','zhangsan1@itcast.cn'),
 ('孙洪山','男',24,'广东','1393518','zhangsan1@gmail.com'),
 ('胡丹丹','女',19,'广西','132138998','zhangsan1@itcast.cn'),
 ('胡书琴','女',30,'广西','152020988','zhangsan1@126.com'),
 ('冷静','男',32,'广东','13422223','lengjing@gmail.com'),
 ('李剑','男',33,'湖南','13423333','lijian@126.com'),
 ('任娟娟','女',21,'广西','13636668','juanjuan@itcast.cn'),
 ('范志坚','男',22,'湖南','1223333','zhijain@126.com'),
 ('王继开','男',21,'海南','1685168','jikai@itcast.cn'),
 ('刘小超','男',21,'广东','1342333','xiaochao@gmail.com');



分析分页对象PageBean

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GkIUtTdS-1599221050539)(assets/image-20200904143840709.png)]



代码

package com.itheima.entity;

import java.util.List;

/**
 * 分页对象
 * 8个属性,分成三大类
 */
public class PageBean<T> {

    //1.从数据库中查询出来的
    private List<T> data;  //每页数据
    private int count;  //总条数

    //2.由用户提供的
    private int current;  //当前页
    private int size;  //每页大小

    //3.由其它的属性计算出来的
    private int first;  //首页
    private int previous;  //上一页
    private int next;  //下一页
    private int total;   //末页/总页数

    public PageBean() {
    }

    //构造方法:封装4个属性
    public PageBean(List<T> data, int count, int current, int size) {
        this.data = data;
        this.count = count;
        this.current = current;
        this.size = size;
    }

    public List<T> getData() {
        return data;
    }

    public void setData(List<T> data) {
        this.data = data;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public int getCurrent() {
        return current;
    }

    public void setCurrent(int current) {
        this.current = current;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    //获取第1页
    public int getFirst() {
        return 1;
    }

    public void setFirst(int first) {
        this.first = first;
    }

    /*
    如果当前页大于1:
        上一页 = 当前页 - 1
    否则返回1
     */
    public int getPrevious() {
        if (getCurrent() > 1) {
            return getCurrent() - 1;
        }
        else {
            return 1;
        }
    }

    public void setPrevious(int previous) {
        this.previous = previous;
    }

    /*
    如果当前页小于最后一页:
        下一页=当前页+1
    否则返回最后一页
     */
    public int getNext() {
        if (getCurrent() < getTotal()) {
            return getCurrent() + 1;
        }
        else {
            return getTotal();
        }
    }

    public void setNext(int next) {
        this.next = next;
    }

    /*
    总记录数 / 页面大小
    如果能整除 正好是这么多页,不能整除就加1页
     */
    public int getTotal() {
        if (getCount() % getSize() == 0) {
            return getCount() / getSize();
        }
        else {
            return getCount() / getSize() + 1;
        }
    }

    public void setTotal(int total) {
        this.total = total;
    }

    //重写toString方法,输出的是get方法中计算结果
    @Override
    public String toString() {
        return "PageBean{" +
                "data=" + getData() +
                ", count=" + getCount() +
                ", current=" + getCurrent() +
                ", size=" + getSize() +
                ", first=" + getFirst() +
                ", previous=" + getPrevious() +
                ", next=" + getNext() +
                ", total=" + getTotal() +
                '}';
    }
}



小结

一共有8个属性:

  1. data,count 从数据库中查询出来
  2. current, size 由用户提交的
  3. first,previous,next,total 通过其它的属性计算出来的



11. 分页查询:SQL语句和DAO层



目标

  1. SQL语句
  2. DAO层
  3. 业务层



序列图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-91yNplIS-1599221050541)(assets/image-20200904145813322.png)]



SQL语句分析

 -- 查询1页的数据,每页显示5条记录. limit 起始行(从0开始),返回行数
  SELECT * FROM contact LIMIT 0,5;  -- 第1页
  SELECT * FROM contact LIMIT 5,5;  -- 第2页
  SELECT * FROM contact LIMIT 10,5;  -- 第3页
  
  -- 查询总记录数
  SELECT COUNT(*) FROM contact;



DAO层代码

/**
 * 查询1页的数据
 */
@Select("SELECT * FROM contact LIMIT #{begin},#{size}")
List<Contact> findContact(@Param("begin") int begin, @Param("size") int size);

/**
 * 查询总记录数
 */
@Select("SELECT COUNT(*) FROM contact")
int findCount();



小结

DAO层需要编写哪两个方法

  1. 查询1页的数据
  2. 查询总记录数



12. 分页查询:业务层



目标

业务层封装成PageBean对象



业务层

功能:通过当前页号和页面大小,得到封装好数据的PageBean对象

/**
 * 查询1页数据,封装成PageBean对象
 * @param current 当前第几页
 * @param size 每页大小
 * @return 封装好所有属性的页面对象
 */
@Override
public PageBean findPageBean(int current, int size) {
    //封装从数据库中查询出来的2个属性
    int begin = (current - 1) * size;  //计算这一页的起始行
    List<Contact> data = contactDao.findContact(begin, size);
    int count = contactDao.findCount();  //查询总条数

    //封装PageBean的四个属性:其中2个从数据库中查询,2个由用户提交
    return new PageBean<>(data,count,current,size);
}



测试类

package com.itheima.test;

import com.itheima.entity.PageBean;
import com.itheima.service.ContactService;
import com.itheima.service.impl.ContactServiceImpl;
import org.junit.Test;

public class TestPageBean {

    @Test
    public void testPageBean() {
        //测试业务层
        ContactService contactService = new ContactServiceImpl();

        PageBean pageBean = contactService.findPageBean(2, 5);
        System.out.println(pageBean);
    }
}



效果

PageBean{data=[Contact{id=6, name='秦婷婷', sex='女', age=25, address='广东', qq='15888802', email='zhangsan1@126.com'}, Contact{id=7, name='折蓉蓉', sex='女', age=30, address='广东', qq='13423333', email='zherong@163.com'}, Contact{id=8, name='曹丽娜', sex='女', age=26, address='广东', qq='12223333', email='zhangsan1@qq.com'}, Contact{id=9, name='李娜', sex='女', age=46, address='广西', qq='1343333', email='zhangsan1@itcast.cn'}, Contact{id=10, name='姜钰', sex='男', age=49, address='湖南', qq='13223333', email='zhangsan1@qq.com'}], count=24, current=2, size=5, first=1, previous=1, next=3, total=5}



小结

业务层做了什么事情?

创建PageBean对象,封装了四个属性:
1. 当前页,用户提供
2. 每页大小,用户提供
3. 每页的数据,从数据库中查询
4. 总记录数,从数据库中查询



13. 分页查询:Servlet



目标

Servlet的实现



步骤

  1. 获取用户输入

    1. 得到当前第几页。如果当前页数为null,则设置为字符串1,默认第1页。
    2. 获取页面大小,如果为null,则设置为字符串5,默认页面的大小是5条。
  2. 调用业务方法,得到PageBean对象
  3. 控制页面的跳转:把pageBean放在request域中,转发到list.jsp页面上显示。



代码

package com.itheima.servlet;

import com.itheima.entity.Contact;
import com.itheima.entity.PageBean;
import com.itheima.service.ContactService;
import com.itheima.service.impl.ContactServiceImpl;

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

@WebServlet("/list")
public class ListContactServlet extends HttpServlet {

    //业务层
    private ContactService contactService = new ContactServiceImpl();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取current和size的值
        String current = request.getParameter("current");
        //设置一个默认值
        if (current == null) {
            current = "1";
        }
        String size = request.getParameter("size");
        if (size == null) {
            size = "5";
        }
        //2.调用业务层获取PageBean对象
        PageBean pageBean = contactService.findPageBean(Integer.parseInt(current), Integer.parseInt(size));
        request.setAttribute("pageBean", pageBean);
        //3.转发到list.jsp页面
        request.getRequestDispatcher("/list.jsp").forward(request, response);
    }

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



小结

Servlet中实现的功能是:

  1. 获取用户提交的current和size值
  2. 调用业务层得到PageBean对象
  3. 转发到list.jsp显示



14. 分页查询:页面大小和下拉列表的处理



目标

  1. 显示1页的数据
  2. 页面大小和下拉列表的处理



首页index.jsp代码

转发给Servlet,并且提交了2个参数

<jsp:forward page="/list">
  <jsp:param name="current" value="1"/>
  <jsp:param name="size" value="5"/>
</jsp:forward>



代码



要点

forEach遍历的是pageBean.data



下拉页码

下拉页码使用forEach循环,显示在下拉列表中



显示分页信息

显示共有多少页,共有多少条记录



代码

<%@ 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">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <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">
        tr, th {
            text-align: center;
        }
    </style>
</head>
<body>
<div class="container">
    <h2 class="text-center">联系人列表</h2>
    <form action="list" method="get" class="form-inline" id="contactForm">
        <div class="row text-right" style="margin-bottom: 10px; margin-top: 15px;">
            <div class="col-md-4 text-left">
                <a class="btn btn-primary" style="width: 120px" href="add.jsp">添加联系人</a>
            </div>
        </div>

        <div class="row">
            <div class="col-md-12">
                <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>
                    <%--
                    items:要遍历的集合
                    var:每次遍历的元素,它是一个变量名,放在页面域中
                    varStauts:状态对象,四个属性:index,count,first,last
                    一开始应该访问/list这个Servlet
                    分页获取的数据在:pageBean.data
                    --%>
                    <c:forEach items="${pageBean.data}" var="contact" varStatus="row">
                        <tr>
                            <td>${row.count}</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>
                                <div class="btn-group btn-group-sm">
                                        <%--query是通过id查询一条记录的servlet--%>
                                    <a class="btn btn-success btn-xs" href="query?id=${contact.id}">修改</a>&nbsp;
                                        <%--href中写javascript:表示,点这个链接调用一个JS代码--%>
                                    <a class="btn btn-info btn-xs" href="javascript:deleteContact('${contact.id}','${contact.name}')">删除</a>
                                </div>
                            </td>
                        </tr>
                    </c:forEach>
                </table>
            </div>
        </div>

        <div class="row text-center">
            <div class="btn-group btn-group-sm">
                <a href="#" class="btn btn-default">首页</a>
                <a href="#" class="btn btn-default">上页</a>
                <a href="#" class="btn btn-default">下页</a>
                <a href="#" class="btn btn-default">末页</a>
            </div>

            每页
            <input type="number" class="form-control" name="size" style="width: 60px;" id="size" value="${pageBean.size}"/>
            条

            第
            <select id="current" class="form-control" name="current">
                <c:forEach begin="1" end="${pageBean.total}" var="num">
                    <option value="${num}">${num}</option>
                </c:forEach>
            </select>
            页/共${pageBean.total}页 共${pageBean.count}条
        </div>
    </form>
</div>

</div>
</body>
<script type="text/javascript">
    //删除联系人前要进行确认, id就是要删除的主键
    function deleteContact(id, name) {
        if (confirm("真的要删除" + name + "这条记录吗?")) {
            //跳转到servlet中
            location.href = "delete?id=" + id;
        }
    }
</script>

</html>



小结

  1. 要遍历的集合从${pageBean.data}取出来
  2. 显示第页多少条,共



    p

    a

    g

    e

    B

    e

    a

    n

    .

    t

    o

    t

    a

    l

    {pageBean.total}页 共







    p


    a


    g


    e


    B


    e


    a


    n


    .


    t


    o


    t


    a


    l












    {pageBean.count}条

  3. 页数下拉列表



15. 分页查询:分页按钮的处理



目标

  1. 页面大小的文本框的改变事件
  2. 跳转到第几页的下拉列表的改变事件



分页按钮

  1. 所有分页链接都调用JS函数:jumpPage(current, size)

    1. 给文本框和下拉列表赋值
    2. 提交表单给servlet
  2. 分页按钮点击,调用上面的函数
  3. 下拉列表的改变时提交表单
  4. 文本框改变时提交表单



代码

<%@ 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">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <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">
        tr, th {
            text-align: center;
        }
    </style>
</head>
<body>
<div class="container">
    <h2 class="text-center">联系人列表</h2>
    <form action="list" method="post" class="form-inline" id="contactForm">
        <div class="row text-right" style="margin-bottom: 10px; margin-top: 15px;">
            <div class="col-md-4 text-left">
                <a class="btn btn-primary" style="width: 120px" href="add.jsp">添加联系人</a>
            </div>
        </div>

        <div class="row">
            <div class="col-md-12">
                <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>
                    <%--
                    items:要遍历的集合
                    var:每次遍历的元素,它是一个变量名,放在页面域中
                    varStauts:状态对象,四个属性:index,count,first,last
                    一开始应该访问/list这个Servlet
                    分页获取的数据在:pageBean.data
                    --%>
                    <c:forEach items="${pageBean.data}" var="contact" varStatus="row">
                        <tr>
                            <%--
                            pageBean.current = 1,2,3
                            row.count= 1~5
                            pageBean.size = 5
                            --%>
                            <td>${(pageBean.current -1) * pageBean.size + row.count}</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>
                                <div class="btn-group btn-group-sm">
                                        <%--query是通过id查询一条记录的servlet--%>
                                    <a class="btn btn-success btn-xs" href="query?id=${contact.id}">修改</a>&nbsp;
                                        <%--href中写javascript:表示,点这个链接调用一个JS代码--%>
                                    <a class="btn btn-info btn-xs" href="javascript:deleteContact('${contact.id}','${contact.name}')">删除</a>
                                </div>
                            </td>
                        </tr>
                    </c:forEach>
                </table>
            </div>
        </div>

        <div class="row text-center">
            <div class="btn-group btn-group-sm">
                <a href="javascript:jumpPage('${pageBean.first}','${pageBean.size}')" class="btn btn-default">首页</a>
                <a href="javascript:jumpPage('${pageBean.previous}','${pageBean.size}')" class="btn btn-default">上页</a>
                <a href="javascript:jumpPage('${pageBean.next}','${pageBean.size}')" class="btn btn-default">下页</a>
                <a href="javascript:jumpPage('${pageBean.total}','${pageBean.size}')" class="btn btn-default">末页</a>
            </div>

            每页
            <input type="number" class="form-control" name="size" style="width: 60px;" id="size" value="${pageBean.size}"/>
            条

            第
            <select id="current" class="form-control" name="current">
                <c:forEach begin="1" end="${pageBean.total}" var="num">
                    <%--如果当前页等于num就选中--%>
                    <option value="${num}" ${pageBean.current == num?'selected="selected"':''}>${num}</option>
                </c:forEach>
            </select>
            页/共${pageBean.total}页 共${pageBean.count}条
        </div>
    </form>
</div>

</div>
</body>
<script type="text/javascript">
    //删除联系人前要进行确认, id就是要删除的主键
    function deleteContact(id, name) {
        if (confirm("真的要删除" + name + "这条记录吗?")) {
            //跳转到servlet中
            location.href = "delete?id=" + id;
        }
    }

    /**
     * 跳到指定的页面
     * @param current 当前页
     * @param size 每页大小
     */
    function jumpPage(current, size) {
        //给size的文本框赋值
        document.getElementById("size").value = size;
        //给下拉列表框赋值
        document.getElementById("current").value = current;
        //提交表单
        document.getElementById("contactForm").submit();
    }

    //页面加载完毕执行
    window.onload = function () {

        //下拉列表改变就提交表单
        document.getElementById("current").onchange = function () {
            //提交表单
            document.getElementById("contactForm").submit();
        };

        //文本框改变就提交表单
        document.getElementById("size").onchange = function () {
            //提交表单
            document.getElementById("contactForm").submit();
        }

    }
</script>
</html>



学习总结

  1. 能够理解添加记录的功能
  2. 能够理解删除多条记录的功能
  3. 能够理解更新记录的功能
  4. 能够理解分页查询所有记录的功能



版权声明:本文为weixin_42530572原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。