J2EE&通用分页02(一)

简介: J2EE&通用分页02

一.重构-提取公用方法        

  1.为了进行公共方法的抽取,需要找出上面实习中的可通用部分,和差异化部分

  • .只要是分页,就会统计总记录数,而总记录数的统计是在业务sql外封装了一个select count(*)是有规律可循的,可以通用
  • 只要是分页,则封装分页sql也是有规律可循的(在业务sql后加limit子句即可),可以通用
  • 因为每个查询对应的业务实体(即模型)不同,所以ORM映射部分不能通用

   2.公用方法封装思路

  • 将可通用的部分封装到模板中
  • 差异化部分(即不可通用部分),可以定义一个处理接口,以便于通过参数传入个性化的实现部分

     3. 具体实现

通用分页查询模板类:

public final class DBTemplate {
  private DBTemplate() {
  }
  public static interface IORMConvert<T> {
    List<T> convert(ResultSet rs) throws SQLException;
  }
  public static <T> List<T> query(String sql, 
      Object[] params, 
      PageBean pageBean, 
      IORMConvert<T> convert) {
    List<T> datas = new ArrayList<>();
    Connection con = null;
    PreparedStatement ps = null;
    ResultSet rs = null;
    //不需要分页
    if (pageBean == null || !pageBean.isPagination()) {
      try {
        con = DBUtil.getConection();
        ps = con.prepareStatement(sql);
        setParam(params, ps);
        rs = ps.executeQuery();
        datas = convert.convert(rs);
        return datas;
      } catch(Exception e) {
        e.printStackTrace();
      } finally {
        DBUtil.closeDB(rs, ps, con);
      }
    } else {
      //1. 查询总记录数
      //2. 查询当前页数据
      //1. 生成统计总记录数的SQL, 查询总记录数
      try {
        String countSql = "select count(*) from (" + sql + ") tmp";
        con = DBUtil.getConection();
        ps = con.prepareStatement(countSql);
        setParam(params, ps);
        rs = ps.executeQuery();
        while(rs.next()) {
          pageBean.setTotal(rs.getInt(1));
        }
        /*
         * 如果统计的总记录数为0,则表示没有符合条件的记录,直接返回一个空结果集即可。
         */
        if(pageBean.getTotal() == 0) {
          return datas;
        }
      } catch (Exception e) {
        e.printStackTrace();
      } finally {
        if(pageBean.getTotal() == 0) {
          DBUtil.closeDB(rs, ps, con);
        }
        DBUtil.closeDB(rs, ps);
      }
      //查询当前页数据
      try {
        String pagingSql = sql 
            + " limit " 
            + pageBean.getStartRow() 
            + ", " 
            + pageBean.getRows();
        ps = con.prepareStatement(pagingSql);
        setParam(params, ps);
        rs = ps.executeQuery();
        datas = convert.convert(rs);
      } catch (SQLException e) {
        e.printStackTrace();
      } finally {
        DBUtil.closeDB(rs, ps, con);
      }
    }
    return datas;
  }
  private static void setParam(Object[] params, PreparedStatement ps) throws SQLException {
    if (params != null) {
      int i = 1;
      for (Object param : params) {
        ps.setObject(i, param);
        i++;
      }
    }
  }
}

使用示例:

public class StudentDao2 {
  public List<Student> getStudents(String sname, PageBean pageBean) {
    String sql = "select * from t_student where sname like ?";
    return DaoTemplate.query(sql, new Object[] {sname}, pageBean, new IORMConvert<Student>() {
      @Override
      public List<Student> convert(ResultSet rs) throws SQLException {
        List<Student> stus = new ArrayList<>();
        while(rs.next()) {
          Student stu = new Student();
          stu.setSid(rs.getInt("sid"));
          stu.setSname(rs.getString("sname"));
          stu.setAge(rs.getInt("age"));
          stu.setRemark(rs.getString("remark"));
          stus.add(stu);
        }
        return stus;
      }
    });
  }
  public static void main(String[] args) {
    StudentDao2 dao = new StudentDao2();
    PageBean pageBean = new PageBean();
    pageBean.setPage(3);
    List<Student> students = dao.getStudents("张%", pageBean);
    students.forEach(s -> System.out.println(s));
  }
}

二.分页标签

2.1 准备一个Servlet

准备一个servlet用于处理请求,获取数据库中的数据,并转发到结果显示页面

@WebServlet(value = "/students")
public class StudentAction extends HttpServlet {
  private static final long serialVersionUID = 3152900867611381148L;
  private StudentDao2 studentDao = new StudentDao2();
  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException {
    doPost(request, response);
  }
  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException {
    PageBean pageBean = new PageBean();
    pageBean.setRequest(request);
    request.setAttribute("pageBean", pageBean);
    String sname = request.getParameter("sname");
    List<Student> students = studentDao.getStudents(sname+"%", pageBean);
    request.setAttribute("students", students);
    System.out.println("dopost .......... ");
    request.getRequestDispatcher("/students/stuList.jsp").forward(request, response);
  }
}

3.2 结果展示页面

创建一个页面,该页面用于显示结果, 使用jstl的c标签来展示结果,为正常使用c标签,需要引入jstl-1.2.jar和standard-1.1.2.jar。

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@taglib prefix="z" uri="/zking" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
  <h1>学生信息</h1>
  <form action="<%=request.getContextPath()%>/students" method="post">
    <input type="text" name="sname">
    <input type="submit" value="查询">
  </form>
  <table border="1" style="width: 98%;">
    <tr>
      <td>学号</td>
      <td>姓名</td>
      <td>年龄</td>
      <td>备注</td>
    </tr>
    <c:forEach items="${students}" var="student">
      <tr>
        <td>${student.sid}</td>
        <td>${student.sname}</td>
        <td>${student.age}</td>
        <td>${student.remark}</td>
      </tr>
    </c:forEach>
<z:paging pageBean="${pageBean}"/>
  </table>
</body>
</html>


相关文章
|
存储 文件存储 Windows
简单好用的免费数据恢复软件EasyRecovery
EasyRecovery是Ontrack公司出品的一个硬盘数据恢复软件,能够帮你恢复丢失的数据以及重建文件系统。它提供了完善的数据恢复解决方案,比如删除文件恢复、格式化恢复、分区丢失恢复。在EasyRecovery 14专业版本中,还可以创建恢复盘和克隆盘,实现整盘的数据恢复及系统迁移。
1015 0
|
前端开发 搜索推荐 JavaScript
ajax的优缺点?
ajax的优缺点?
150 0
|
Java 中间件 测试技术
java依赖冲突解决问题之jar包版本冲突无法通过升降级解决时如何解决
java依赖冲突解决问题之jar包版本冲突无法通过升降级解决时如何解决
|
10月前
|
存储 搜索推荐 算法
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
392 16
|
6月前
|
SQL 数据处理 数据库
《深入SQL子查询:解锁查询的高级智慧》
子查询是SQL中一项强大特性,作为嵌套在主查询中的小型查询任务,它为主查询提供数据支持或条件限定。子查询分为单行、多行和相关子查询三种类型,广泛应用于WHERE、FROM和SELECT子句中,可简化复杂查询逻辑、增强灵活性并实现多层次数据筛选与计算。然而,子查询也可能带来性能下降和维护困难等问题。优化策略包括减少嵌套、合理使用索引及权衡子查询与JOIN的使用,以提升查询效率和可读性。掌握子查询的本质与技巧,能帮助开发者更高效地处理复杂数据任务。
146 8
|
11月前
|
网络协议 Linux 网络性能优化
Linux C/C++之TCP / UDP通信
这篇文章详细介绍了Linux下C/C++语言实现TCP和UDP通信的方法,包括网络基础、通信模型、编程示例以及TCP和UDP的优缺点比较。
437 0
Linux C/C++之TCP / UDP通信
|
SQL 数据库 开发者
SQL事务处理与并发控制:保障数据一致性的关键——深入探索ACID原则、锁定与乐观并发控制策略,以及高级事务管理技巧
【8月更文挑战第31天】在数据库管理和应用开发中,确保数据一致性至关重要。SQL事务处理和并发控制是实现这一目标的关键技术,它们保证了多用户同时访问和修改数据时数据库的一致性和准确性。事务处理遵循ACID原则(原子性、一致性、隔离性和持久性),并发控制则通过锁定和乐观并发控制等策略管理多用户访问,防止数据冲突。本文将深入探讨这些技术的原理与应用,帮助开发者更好地保护数据。
219 0
|
安全 数据安全/隐私保护 开发者
Python实现简单的邮件发送系统
Python实现简单的邮件发送系统
162 3
|
存储 JavaScript 前端开发
|
运维
【运维杂谈】用配置审计,保护你的阿里云账户余额
【运维杂谈】用配置审计,保护你的阿里云账户余额
214 0