学习目标

案例一-显示所有联系人案例

一,案例需求

img

  • 说白了就是从数据库中将所有联系人的数据查询出来,在list.jsp页面进行展示给用户

二,技术分析

​ 传统方式的开发一个请求对应一个Servlet:这样的话会导致一个模块的Servlet过多,导致整个项目的Servlet都会很多. 能不能做一个处理?让一个模块用一个Servlet处理请求. 当前是联系人模块, 就创建一个LinkManServlet

@WebServlet("/linkMan")
public class LinkManServlet extends HttpServlet {
    /*
        【联系人】传统方式:
            查看:http://localhost:8080/day27/findAll          FindAllServlet
            增加:http://localhost:8080/day27/add              AddServlet
            删除:http://localhost:8080/day27/delete           DeleteServlet
            分页:http://localhost:8080/day27/findPage         FindPageServlet
       以模块为单位:  这个method是请求参数 名称随便起
            查看:http://localhost:8080/day27/linkMan?method=findAll         LinkManServlet
            增加:http://localhost:8080/day27/linkMan?method=add            LinkManServlet
            删除:http://localhost:8080/day27/linkMan?method=delete         LinkManServlet
            分页:http://localhost:8080/day27/linkMan?method=findPage         LinkManServlet
       问题:在doPost方法中进行请求处理时如何区分具体要完成什么操作?

     */

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //0.中文乱码处理
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        //1.获取请求参数method的值,
        String methodStr = request.getParameter("method");
        //2.根据参数值执行对应的操作
        if ("findAll".equals(methodStr)){
            findAll(request, response);
        }else if("add".equals(methodStr)){
            add(request, response);
        }else if("delete".equals(methodStr)){
            delete(request, response);
        }else if("findPage".equals(methodStr)){
            findPage(request, response);
        }
    }

    //查看所有联系人
    public void findAll(HttpServletRequest request, HttpServletResponse response){
        System.out.println("查询所有联系人...");
        //1.获取请求参数
        //2.调用业务处理
        //3.响应
    }

    //增加联系人
    public void add(HttpServletRequest request, HttpServletResponse response){
        System.out.println("增加联系人...");
        //1.获取请求参数
        //2.调用业务处理
        //3.响应
    }

    //删除联系人
    public void delete(HttpServletRequest request, HttpServletResponse response){
        System.out.println("删除联系人...");
        //1.获取请求参数
        //2.调用业务处理
        //3.响应
    }

    //分页查看联系人
    public void findPage(HttpServletRequest request, HttpServletResponse response){
        System.out.println("分页查看联系人...");
        //1.获取请求参数
        //2.调用业务处理
        //3.响应
    }

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

三, 思路分析

image-20210817092207992

四, 代码实现

1.准备工作

  • 数据库的创建
create database day28;

use day28;

CREATE TABLE linkman (
  id int primary key auto_increment,
  name varchar(50),
  sex varchar(50),
  age int,
  address varchar(50),
  qq varchar(50),
  email varchar(50)
);

INSERT INTO `linkman`  (`id`, `name`, `sex`, `age`, `address`, `qq`, `email`) VALUES
(null, '张三', '男', 11, '广东', '766335435', '766335435@qq.com'),
(null, '李四', '男', 12, '广东', '243424242', '243424242@qq.com'),
(null, '王五', '女', 13, '广东', '474574574', '474574574@qq.com'),
(null, '赵六', '女', 18, '广东', '77777777', '77777777@qq.com'),
(null, '钱七', '女', 15, '湖南', '412132145', '412132145@qq.com'),
(null, '王八', '男', 25, '广西', '412132775', '412132995@qq.com');
  • JavaBean的创建
package com.itheima.bean;

import java.io.Serializable;

public class LinkMan implements Serializable {
    private int id;
    private String name;
    private String sex;
    private int age;
    private String address;
    private String qq;
    private String email;

    public LinkMan() {
    }

    public LinkMan(int id, String name, String sex, int age, String address, String qq, String email) {
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.address = address;
        this.qq = qq;
        this.email = 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 "LinkMan{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                ", qq='" + qq + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}
  • jar包
  • 工具类
  • 配置文件
  • 页面

2.代码

  • 页面 index.jsp
<a href="linkMan?method=findAll">查询所有联系人</a>
  • LinkManServlet
@WebServlet("/linkMan")
public class LinkManServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //0.中文乱码处理
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        //1.获取请求参数method的值,
        String methodStr = request.getParameter("method");
        //2.根据参数值执行对应的操作
        if ("findAll".equals(methodStr)){
            findAll(request, response);
        }else if("add".equals(methodStr)){
            add(request, response);
        }else if("delete".equals(methodStr)){
            delete(request, response);
        }else if("findPage".equals(methodStr)){
            findPage(request, response);
        }
    }

    //查看所有联系人
    public void findAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("查询所有联系人...");
        try {
            //1.获取请求参数
            //2.调用业务处理
            LinkManService linkManService = new LinkManService();
            List<LinkMan> list = linkManService.findAll();
            System.out.println("list = " + list);
            //3.响应
            //3.1:将联系人数据集合存储到request域对象中
            request.setAttribute("list",list);
            //3.2:使用转发跳转到list.jsp页面
            request.getRequestDispatcher("list.jsp").forward(request,response);
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().print("服务器异常!");
        }
    }

    //增加联系人
    public void add(HttpServletRequest request, HttpServletResponse response){
        System.out.println("增加联系人...");
        //1.获取请求参数
        //2.调用业务处理
        //3.响应
    }

    //删除联系人
    public void delete(HttpServletRequest request, HttpServletResponse response){
        System.out.println("删除联系人...");
        //1.获取请求参数
        //2.调用业务处理
        //3.响应
    }

    //分页查看联系人
    public void findPage(HttpServletRequest request, HttpServletResponse response){
        System.out.println("分页查看联系人...");
        //1.获取请求参数
        //2.调用业务处理
        //3.响应
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
  • LinkManService
public class LinkManService {
    /**
     * 查询所有联系人
     * @return 联系人list集合
     */
    public List<LinkMan> findAll() throws SQLException {
        //调用dao
        LinkManDao linkManDao = new LinkManDao();
        return linkManDao.findAll();
    }
}
  • LinkManDao
public class LinkManDao {

    //查询所有联系人
    public List<LinkMan> findAll() throws SQLException {
        //操作数据库
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
        String sql = "select * from linkman";
        return queryRunner.query(sql,new BeanListHandler<LinkMan>(LinkMan.class));
    }
}
  • list.jsp
<%--每一条联系人信息都是一行 List<LinkMan>--%>
<%--使用jstl的forEach标签遍历 每遍历一次 都表示输出一行联系人信息--%>
<c:forEach items="${list}" var="linkman">
    <tr>
        <td>${linkman.id}</td>
        <td>${linkman.name}</td>
        <td>${linkman.sex}</td>
        <td>${linkman.age}</td>
        <td>${linkman.address}</td>
        <td>${linkman.qq}</td>
        <td>${linkman.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>

五,小结

  1. 用户在浏览器发起请求 linkMan?mthod=findAll

  2. 编写Servlet的findAll方法

    //1.调用业务处理 获取联系人数据集合List<LinkMan>
    //2.响应
    //2.1:将list集合存入request域对象
    //2.2:使用转发跳转到list.jsp
    
  3. 编写Service

  4. 编写Dao

  5. 将list集合数据获取填充到list.jsp页面

    <%--使用forEach标签遍历数据展示  每遍历一次 就是输出一行联系人信息展示--%>
            <c:forEach items="${list}" var="linkman">
                <tr>
                    <td>${linkman.id}</td>
                    <td>${linkman.name}</td>
                    <td>${linkman.sex}</td>
                    <td>${linkman.age}</td>
                    <td>${linkman.address}</td>
                    <td>${linkman.qq}</td>
                    <td>${linkman.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>
    

案例二:添加联系人

一,案例需求

  1. 点击添加联系人跳转添加联系人页面

    image-20191120151947155

  2. 在添加联系人页面,点击提交按钮,把数据提交到服务器,保存到数据库

    image-20191120152002082

  3. 在添加完成,重新查询所有联系人进行展示! 可以查看到新建的联系人信息

    image-20191120152015188

二,思路分析

image-20210817104204861

三代码实现

  • LinkManServlet
@WebServlet("/linkMan")
public class LinkManServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //0.中文乱码处理
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        //1.获取请求参数method的值,
        String methodStr = request.getParameter("method");
        //2.根据参数值执行对应的操作
        if ("findAll".equals(methodStr)){
            findAll(request, response);
        }else if("add".equals(methodStr)){
            add(request, response);
        }else if("delete".equals(methodStr)){
            delete(request, response);
        }else if("findPage".equals(methodStr)){
            findPage(request, response);
        }
    }

    //查看所有联系人
    public void findAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("查询所有联系人...");
        try {
            //1.获取请求参数
            //2.调用业务处理
            LinkManService linkManService = new LinkManService();
            List<LinkMan> list = linkManService.findAll();
            System.out.println("list = " + list);
            //3.响应
            //3.1:将联系人数据集合存储到request域对象中
            request.setAttribute("list",list);
            //3.2:使用转发跳转到list.jsp页面
            request.getRequestDispatcher("list.jsp").forward(request,response);
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().print("服务器异常!");
        }
    }

    //增加联系人
    public void add(HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.out.println("增加联系人...");
        try {
            //1.获取请求参数【要添加的联系人信息】
            Map<String, String[]> parameterMap = request.getParameterMap();

            //2.将联系人信息封装到LinkMan对象中  注意:Map集合的key要和javabean的属性一致
            LinkMan linkMan = new LinkMan();
            BeanUtils.populate(linkMan,parameterMap);

            //3.调用业务处理
            LinkManService linkManService = new LinkManService();
            int rows = linkManService.add(linkMan);
            //4.响应  无论添加成功与否 都重新查询数据展示所有联系人
            //方式一:调用findAll()方法 或转发到 linkMan?method=findAll
            //方式一缺陷:由于添加完联系人 使用的是转发跳转,因此地址栏没有发送改变,并且请求信息也没有丢失 所以一旦刷新页面,就会导致表单重复提交!!!
            //findAll(request, response);
            //因此 在增删改操作后 需要查询查询显示数据 不使用转发跳转 使用重定向!!!
            response.sendRedirect("linkMan?method=findAll");

        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().print("服务器异常!");
        }
    }

    //删除联系人
    public void delete(HttpServletRequest request, HttpServletResponse response){
        System.out.println("删除联系人...");
        //1.获取请求参数
        //2.调用业务处理
        //3.响应
    }

    //分页查看联系人
    public void findPage(HttpServletRequest request, HttpServletResponse response){
        System.out.println("分页查看联系人...");
        //1.获取请求参数
        //2.调用业务处理
        //3.响应
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
  • LinkManService
public class LinkManService {

    /**
     * 添加联系人
     * @param linkMan 要添加的联系人对象
     * @return 受影响的行数
     */
    public int add(LinkMan linkMan) throws SQLException {
        //调用dao
        LinkManDao linkManDao = new LinkManDao();
        return linkManDao.add(linkMan);
    }
}
  • LinkManDao
public class LinkManDao {

    //增加联系人
    public int add(LinkMan linkMan) throws SQLException {
        //操作数据库
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
        String sql = "insert into linkman values(null,?,?,?,?,?,?)";
        return queryRunner.update(sql,linkMan.getName(),linkMan.getSex(),linkMan.getAge(),linkMan.getAddress(),linkMan.getQq(),linkMan.getEmail());
    }
}

四,小结

需求:向数据库表中插入一条数据

流程:add.jsp->提交-->linkMan?method=add-->linkMan?method=findAll

思路:

  1. 设置add.jsp中表单的提交地址action为linkMan?method=add

  2. 在LinkManServlet的add方法中进行添加处理

    //1.获取请求参数  封装到LinkMan对象
    //2.调用业务处理
    //3.响应 无论添加成功还是失败 都重新查询所有联系人展示
    //注意:要使用重定向
    response.sendRedirect("linkMan?method=findAll");
    
  3. 编写Service

  4. 编写Dao

案例三:删除联系人

一,案例需求

1533811173975

删除:删除数据库表中一条记录

点击确定删除之后, 删除成功与否,再重新查询所有联系人展示,

二,思路分析

image-20210731123011383

三,代码实现

  • 页面代码
<%--删除 没有必要重新打开一个页面 它是根据id进行删除 因此需要删除超链接的href属性--%>
<%--点击删除 弹窗确认对话框  此时需要给删除按钮 绑定一个点击事件 --%>
<a class="btn btn-default btn-sm" onclick="deleteById(${linkman.id})" >删除</a>
<script>
    function deleteById(id) {
        var flag = confirm("确定要删除吗?");
        if(flag){
            //1.获取要删除的联系人id
            console.log("要删除的联系人id:"+id);
            //2.向后台发起请求根据联系人id删除联系人  linkMan?method=delete&id=?
            //js的页面跳转
            location.href = "linkMan?method=delete&id="+id;
        }
    }
</script>
  • LinkManServlet
@WebServlet("/linkMan")
public class LinkManServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //0.中文乱码处理
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        //1.获取请求参数method的值,
        String methodStr = request.getParameter("method");
        //2.根据参数值执行对应的操作
        if ("findAll".equals(methodStr)){
            findAll(request, response);
        }else if("add".equals(methodStr)){
            add(request, response);
        }else if("delete".equals(methodStr)){
            delete(request, response);
        }else if("findPage".equals(methodStr)){
            findPage(request, response);
        }
    }

    //查看所有联系人
    public void findAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("查询所有联系人...");
        try {
            //1.获取请求参数
            //2.调用业务处理
            LinkManService linkManService = new LinkManService();
            List<LinkMan> list = linkManService.findAll();
            System.out.println("list = " + list);
            //3.响应
            //3.1:将联系人数据集合存储到request域对象中
            request.setAttribute("list",list);
            //3.2:使用转发跳转到list.jsp页面
            request.getRequestDispatcher("list.jsp").forward(request,response);
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().print("服务器异常!");
        }
    }

    //增加联系人
    public void add(HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.out.println("增加联系人...");
        try {
            //1.获取请求参数【要添加的联系人信息】
            Map<String, String[]> parameterMap = request.getParameterMap();

            //2.将联系人信息封装到LinkMan对象中  注意:Map集合的key要和javabean的属性一致
            LinkMan linkMan = new LinkMan();
            BeanUtils.populate(linkMan,parameterMap);

            //3.调用业务处理
            LinkManService linkManService = new LinkManService();
            int rows = linkManService.add(linkMan);
            //4.响应  无论添加成功与否 都重新查询数据展示所有联系人
            //方式一:调用findAll()方法 或转发到 linkMan?method=findAll
            //方式一缺陷:由于添加完联系人 使用的是转发跳转,因此地址栏没有发送改变,并且请求信息也没有丢失 所以一旦刷新页面,就会导致表单重复提交!!!
            //findAll(request, response);
            //因此 在增删改操作后 需要查询查询显示数据 不使用转发跳转 使用重定向!!!
            response.sendRedirect("linkMan?method=findAll");

        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().print("服务器异常!");
        }
    }

    //删除联系人
    public void delete(HttpServletRequest request, HttpServletResponse response) throws IOException {
        try {
            System.out.println("删除联系人...");
            //1.获取请求参数【要删除的联系人id】
            String id = request.getParameter("id");
            //2.调用业务处理
            LinkManService linkManService = new LinkManService();
            int rows = linkManService.delete(Integer.parseInt(id));
            //3.响应【无论删除成功与否都需要重新查询数据展示  重定向到linkMan?method=findAll】
            response.sendRedirect("linkMan?method=findAll");
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().print("服务器异常!");
        }
    }

    //分页查看联系人
    public void findPage(HttpServletRequest request, HttpServletResponse response){
        System.out.println("分页查看联系人...");
        //1.获取请求参数
        //2.调用业务处理
        //3.响应
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
  • LinkManService
public class LinkManService {
   
    /**
     * 删除联系人
     * @param id 要删除的联系人id
     * @return 受影响的行数
     */
    public int delete(int id) throws SQLException {
        //调用dao
        LinkManDao linkManDao = new LinkManDao();
        return linkManDao.delete(id);
    }
}
  • LinkManDao
public class LinkManDao {

    //查询所有联系人
    public List<LinkMan> findAll() throws SQLException {
        //操作数据库
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
        String sql = "select * from linkman";
        return queryRunner.query(sql,new BeanListHandler<LinkMan>(LinkMan.class));
    }

    //增加联系人
    public int add(LinkMan linkMan) throws SQLException {
        //操作数据库
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
        String sql = "insert into linkman values(null,?,?,?,?,?,?)";
        return queryRunner.update(sql,linkMan.getName(),linkMan.getSex(),linkMan.getAge(),linkMan.getAddress(),linkMan.getQq(),linkMan.getEmail());
    }

    //删除联系人
    public int delete(int id) throws SQLException {
        //操作数据库
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
        String sql = "delete from linkman where id=?";
        return queryRunner.update(sql,id);
    }
}

四,小结

  1. 需求:根据id去到数据库删除一条记录

  2. 流程:点击删除按钮--> 弹出确认对话框-->点击确定-->向后台发起删除请求

    //js的跳转
    location.href = "linkMan?method=delete&id="+id;
    
  3. 思路:

    1. 在页面向linkMan?method=delete发起请求

    2. 编写Servlet

      //1.获取请求参数 要删除的联系人id
      //2.调用业务处理
      //3.响应 无论删除成功还是失败 都重新查询显示所有联系人 重定向到linkMan?method=findAll
      
    3. 编写Service

    4. 编写Dao

案例四:分页展示联系人

一,案例需求

1533810941749

  • 分页查询出联系人信息

二,技术分析

1,数据库操作 limit

-- 分页处理 
/*
  本质:分页查询 根据你提供的页码和每页显示的条数去数据库中查询出对应页码的数据
  SELECT * FROM linkMan LIMIT a,b
  a:从第几条开始查询 起始下标  (curPageNo-1)*pageSize
  b:每页显示几条               pageSize
*/
-- MySQL分页语句
-- 需求:每页显示5条 要求查询第一页的数据
SELECT * FROM linkman LIMIT 0,5
-- 需求:每页显示5条 要求查询第二页的数据
SELECT * FROM linkman LIMIT 5,5
-- 需求:每页显示5条 要求查询第三页的数据
SELECT * FROM linkman LIMIT 10,5

-- 分页查询:当前页码:curPageNo 每页显示条数:pageSize 总条数:total  总页数:pages
-- 分页:分页时需要判断页码 当前页码<总页数 
-- 总页数如何得到:总条数/每页显示条数  total%pageSize==0?total/pageSize:total/pageSize+1
-- 得到总条数?
SELECT COUNT(*) FROM linkman

2. 分页需要的数据的封装

image-20210817112059247

package com.itheima.bean;

import java.io.Serializable;
import java.util.List;

public class PageBean implements Serializable {
    private int curPageNo;      //当前页码
    private int pageSize;       //每页显示条数
    private long total;         //总条数   原因:因为select  count(*) from 表 返回的结果是long类型
    private int pages;          //总页数
    private List<LinkMan> list; //每页显示的数据

    @Override
    public String toString() {
        return "PageBean{" +
                "curPageNo=" + curPageNo +
                ", pageSize=" + pageSize +
                ", total=" + total +
                ", pages=" + pages +
                ", list=" + list +
                '}';
    }

    public PageBean() {
    }

    public PageBean(int curPageNo, int pageSize, long total, int pages, List<LinkMan> list) {
        this.curPageNo = curPageNo;
        this.pageSize = pageSize;
        this.total = total;
        this.pages = pages;
        this.list = list;
    }

    public int getCurPageNo() {
        return curPageNo;
    }

    public void setCurPageNo(int curPageNo) {
        this.curPageNo = curPageNo;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public long getTotal() {
        return total;
    }

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

    public int getPages() {
        return pages;
    }

    public void setPages(int pages) {
        this.pages = pages;
    }

    public List<LinkMan> getList() {
        return list;
    }

    public void setList(List<LinkMan> list) {
        this.list = list;
    }
}

三,思路分析

image-20210731115835293

四,代码实现

  • LinkManServlet
package com.itheima.web;

import com.itheima.bean.LinkMan;
import com.itheima.bean.PageBean;
import com.itheima.service.LinkManService;
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.List;
import java.util.Map;

@WebServlet("/linkMan")
public class LinkManServlet extends HttpServlet {
    /*
        【联系人】传统方式:
            查看:http://localhost:8080/day27/findAll          FindAllServlet
            增加:http://localhost:8080/day27/add              AddServlet
            删除:http://localhost:8080/day27/delete           DeleteServlet
            分页:http://localhost:8080/day27/findPage         FindPageServlet
       以模块为单位:  这个method是请求参数 名称随便起
            查看:http://localhost:8080/day27/linkMan?method=findAll         LinkManServlet
            增加:http://localhost:8080/day27/linkMan?method=add            LinkManServlet
            删除:http://localhost:8080/day27/linkMan?method=delete         LinkManServlet
            分页:http://localhost:8080/day27/linkMan?method=findPage         LinkManServlet
       问题:在doPost方法中进行请求处理时如何区分具体要完成什么操作?

     */

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //0.中文乱码处理
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        //1.获取请求参数method的值,
        String methodStr = request.getParameter("method");
        //2.根据参数值执行对应的操作
        if ("findAll".equals(methodStr)){
            findAll(request, response);
        }else if("add".equals(methodStr)){
            add(request, response);
        }else if("delete".equals(methodStr)){
            delete(request, response);
        }else if("findPage".equals(methodStr)){
            findPage(request, response);
        }
    }

    //分页查看联系人
    public void findPage(HttpServletRequest request, HttpServletResponse response) throws IOException {
        try {
            System.out.println("分页查看联系人...");
            //1.获取请求参数【当前页码和每页显示条数】
            String curPageNoStr = request.getParameter("curPageNo");
            String pageSizeStr = request.getParameter("pageSize");
            //如果前端没有传递当前页码和每页显示条数 则默认当前页码为1,每页显示5条
            int curPageNo = 1;
            int pageSize = 5;
            if(curPageNoStr!=null && !curPageNoStr.equals("")){
                curPageNo = Integer.parseInt(curPageNoStr);
            }
            if(pageSizeStr!=null && !pageSizeStr.equals("")) {
                pageSize = Integer.parseInt(pageSizeStr);
            }
            //2.调用业务处理【返回分页所需数据 PageBean对象】
            LinkManService linkManService = new LinkManService();
            PageBean pageBean = linkManService.findPage(curPageNo,pageSize);

            System.out.println("pageBean = " + pageBean);

            //3.响应 将PageBean存入到request域对象中 转发到list_page.jsp页面进行分页数据展示
            request.setAttribute("page",pageBean);
            request.getRequestDispatcher("list_page.jsp").forward(request,response);
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().print("服务器异常!");
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
  • LinkManService
public class LinkManService {
   
    /**
     * 分页查询 将分页所需数据封装到PageBean对象中
     * @param curPageNo 当前页码
     * @param pageSize  每页显示条数
     * @return 分页所需数据
     */
    public PageBean findPage(int curPageNo, int pageSize) throws SQLException {
        //1.封装PageBean对象
        PageBean pageBean = new PageBean();

        pageBean.setCurPageNo(curPageNo);
        pageBean.setPageSize(pageSize);
        //1.1:查询总条数 调用dao
        LinkManDao linkManDao = new LinkManDao();
        long total = linkManDao.findCount();
        pageBean.setTotal(total);
        //1.2:计算总页数
        int pages = (int) (total%pageSize==0?total/pageSize:total/pageSize+1);
        pageBean.setPages(pages);
        //1.3:每页显示数据
        List<LinkMan> list = linkManDao.findList(curPageNo,pageSize);
        pageBean.setList(list);

        //2.返回PageBean对象
        return pageBean;
    }
}
  • LinkManDao
public class LinkManDao {

    //查询总条数
    public long findCount() throws SQLException {
        //操作数据库
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
        String sql = "select count(*) from linkman";
        return (long) queryRunner.query(sql,new ScalarHandler());
    }

    //查询每页显示的数据
    public List<LinkMan> findList(int curPageNo, int pageSize) throws SQLException {
        //操作数据库
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
        String sql = "select * from linkman limit ?,?";
        return queryRunner.query(sql,new BeanListHandler<>(LinkMan.class),(curPageNo-1)*pageSize,pageSize);
    }
}

list_page.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<!-- 网页使用的语言 -->
<html lang="zh-CN">
<head>
    <!-- 指定字符集 -->
    
    <!-- 使用Edge最新的浏览器的渲染方式 -->
    
    <!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。
    width: 默认宽度与设备的宽度相同
    initial-scale: 初始的缩放比,为1: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>
        <%--每遍历一次 就输出一行联系人信息--%>
        <c:forEach items="${page.list}" var="linkman">
            <tr>
                <td>${linkman.id}</td>
                <td>${linkman.name}</td>
                <td>${linkman.sex}</td>
                <td>${linkman.age}</td>
                <td>${linkman.address}</td>
                <td>${linkman.qq}</td>
                <td>${linkman.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">
				<ul class="pagination success">
                    <%--上一页  当前页码大于1,才会有上一页--%>
                    <c:if test="${page.curPageNo>1}">
                        <li><a href="linkMan?method=findPage&curPageNo=${page.curPageNo-1}" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>
                    </c:if>

					<%--具体的页码 从第一页 到 总页数--%>
                    <%--使用forEach简单遍历--%>
                    <c:forEach var="i" begin="1" end="${page.pages}">
                        <%--如果是当前页 高亮显示页码--%>
                        <c:choose>
                            <c:when test="${page.curPageNo == i}">
                                <li class="active"><a href="linkMan?method=findPage&curPageNo=${i}">${i}</a></li>
                            </c:when>
                            <c:otherwise>
                                <li><a href="linkMan?method=findPage&curPageNo=${i}">${i}</a></li>
                            </c:otherwise>
                        </c:choose>
                    </c:forEach>

					<%--下一页 当前页码小于总页数的时候  才有下一页--%>
                     <c:if test="${page.curPageNo<page.pages}">
                         <li><a href="linkMan?method=findPage&curPageNo=${page.curPageNo+1}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>
                     </c:if>

				</ul>
            </td>
        </tr>
    </table>
</div>
</body>
</html>

五,小结

  1. 数据库技术

    -- 查询分页数据
    select * from 表 limit a,b
    --   a:表示从第几条开始查询  起始下标   a=(curPageNo-1)*pageSize
    --   b:每页显示条数   pageSize
    -- 查询总条数  total
    select count(*) from 表
    -- 计算总页数
    pages = total%pageSize==0?total/pageSize:total/pageSize+1;
    
  2. 分页所需数据封装

    public class PageBean{
        private int curPageNo;//当前页码
        private int pageSize;//每页显示条数
        private long total;//总条数
        private int pages;//总页数
        private List<LinkMan> list;//当前页数据集合
    }
    
  3. 思路

    1. 在浏览器向linkMan?method=findPage&curPageNo=1发起请求

    2. 编写LinkManServlet的findPage方法

      findPage(request,response){
         	//1.获取请求参数 【当前页码、每页显示条数】
         	//2.调用业务处理 【得到分页所需数据封装的PageBean对象】
          //3.响应
          //3.1:将PageBean对象存入request作用域
          //3.2:转发到list_page.jsp展示分页数据
      }
      
    3. 编写LinkManService

      //1.查询总条数,计算总也数
      //2.查询当前页数据集合list
      //3.将分页所需数据封装到PageBean对象返回
      
    4. 编写LinManDao

      //1.查询总条数 total
      //2.查询当前页数据集合  list
      

扩展

1.PageBean优化【使用泛型】

public class PageBean<T> {
    private int curPageNo;      //当前页码
    private int pageSize;       //每页显示条数
    private long total;         //总条数   原因:因为select  count(*) from 表 返回的结果是long类型
    private int pages;          //总页数
    private List<T> list; //每页显示的数据
  }

2,模块Servlet优化

  1. 问题:

    1563594629365

    • doGet()方法里面的 if 太多, 可读性很差
    • doGet()方法里面, 每加一个请求, 都需要添加一个if, 维护麻烦
  2. 解决: 反射 根据传入的方法名进行方法动态调用

    • 一个if都不要
    • 优化之后, 代码就不变了, 不会随着请求的增加而增加if
    @WebServlet(value = "/linkMan")
    public class LinkManServlet extends HttpServlet {
    
        //查询所有联系人 http://localhost:8080/day28/linkMan?method=findAll
        //增加联系人 http://localhost:8080/day28/linkMan?method=add
        //删除联系人 http://localhost:8080/day28/linkMan?method=delete
        //分页展示联系人 http://localhost:8080/day28/linkMan?method=findPage
        //...
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            try {
                //0.处理请求响应中文乱码
                request.setCharacterEncoding("UTF-8");
                response.setContentType("text/html;charset=UTF-8");
                //1.获取method参数 判断要进行具体哪一种操作
                String methodStr = request.getParameter("method");
                //特点:①每个方法名都和method参数名称相同  ②每个方法的参数都是一样的
                //优化:根据method参数值去调用相应的方法执行处理请求   使用反射:Method对象.invoke(Object o,params...);
                //1.获取字节码对象
                Class c = this.getClass();
                //2.根据方法名称获取指定的Method对象
                //getMethod():获取的是public修饰的方法    getDeclaredMethod():获取当前类中任意修饰符修饰的方法
                Method method = c.getMethod(methodStr, HttpServletRequest.class, HttpServletResponse.class);
                //3.使用Method对象调用方法
                method.invoke(this,request,response);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    }
    

image-20210710151031466

posted on 2022-04-24 23:12  ofanimon  阅读(55)  评论(0编辑  收藏  举报
// 侧边栏目录 // https://blog-static.cnblogs.com/files/douzujun/marvin.nav.my1502.css