JDBC分页查询及实现

本文探讨了数据库分页查询的重要性,详细解释了物理分页和逻辑分页的区别,重点介绍了如何利用JDBC和MySQL实现物理分页查询。通过实例展示了如何创建JavaBean、DAO以及Servlet来实现商品信息的分页展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当数据过多时,一页之内是无法显示的,因此需要进行分页显示。
(一)分页技术实现:
物理分页:
- 在数据库执行查询时(实现分页查询),查询需要的数据—-依赖数据库的SQL语句
- 在sql查询时,从数据库只检索分页需要的数据
- 通常不同的数据库有着不同的物理分页语句
- 物理分页:Mysql/SQL Server/Oracle,每种数据数的写法是不同的
- mysql物理分页,采用limit关键字,SQL Server采用top,Oracle采用rowNum
- 例如,检索11-20条:select * from user limit 10,10;注意,索引从0开始,第一个10代表第11条,上述语句的含义是查询第11条到第20条

逻辑分页:
- 先查询所有数据到内存,再从内存截取需要的数据—-采用程序内部逻辑(先都查出来,再进行选择)
- 在sql查询时,先从数据库检索出所有数据的结果集
- 在程序内,通过逻辑语句获得分页需要的数据
- 例如,检索11-20条:userList.subList(10,20);
- ResultSet是JDBC API中封装的查询结果集对象,通过该对象可以实现数据的分页显示。通过ResultSet的光标实现分页,优点是在各种数据库上通用,缺点是占用大量资源,不适合数据量大的情况。(由于ResultSet分页存在性能方面的缺陷,在实际开发中,很多情况都是采用数据库提供的分页机制来实现分页查询功能)

(二)实例
通过MySQL数据库提供的分页机制,实现商品信息的分页查询功能,将分页数据显示在JSP页面
(1)JavaBean:用于封装商品信息

public class Product{
    public static final int PAGE_SIZE = 2//每页记录数
    private int id;//编号
    private String name;//名称
    private double price;//价格
    private int num;//数量
    private String unit;//单位
    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 double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public int getNum() {
        return num;
    }
    public void setNum(int num) {
        this.num = num;
    }
    public String getUnit() {
        return unit;
    }
    public void setUnit(String unit) {
        this.unit = unit;
    }
}

由于每页记录数一般不会修改,因此将其定义为final类型(静态的final类型变量,通常情况下我们大写)。

按照DAO模式,接下来我们分别编写数据层和业务层

(2)创建名称为BookDao的类,用于封装数据库相关操作。

package com.megustas.bean;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

/**
 * 商品数据库操作
 * @author Megustas
 *
 */

public class BookDao {
    /**
     * 获取数据库连接
     * @return Connection对象
     */
    public Connection getConnection(){
        // 数据库连接,注意四个参数需要完全(加载,url,用户名,密码)
        Connection conn = null;
        try {
            // 加载数据库驱动,注册到驱动管理器
            Class.forName("com.mysql.jdbc.Driver");
            // 数据库连接字符串
            String url = "jdbc:mysql://localhost:3306/db_database10";
            // 数据库用户名
            String username = "root";
            // 数据库密码
            String password = "111";
            // 创建Connection连接
            conn = DriverManager.getConnection(url,username,password);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        // 返回数据库连接
        return conn;
    }

    /**
     * 分页查询所有商品信息
     * @param page 页数
     * @return List<Product>
     */
    public List<Product> find(int page){
        // 创建List
        List<Product> list = new ArrayList<Product>();
        // 获取数据库连接
        Connection conn = getConnection();
        // 分页查询的SQL语句
        String sql = "select * from tb_product order by id desc limit ?,?";
        try {
            // 获取PreparedStatement
            PreparedStatement ps = conn.prepareStatement(sql);
            // 对SQL语句中的第1个参数赋值
            ps.setInt(1, (page - 1) * Product.PAGE_SIZE);
            // 对SQL语句中的第2个参数赋值
            ps.setInt(2, Product.PAGE_SIZE);
            // 执行查询操作
            ResultSet rs = ps.executeQuery();
            // 光标向后移动,并判断是否有效
            while(rs.next()){
                // 实例化Product
                Product p = new Product();
                // 对id属性赋值
                p.setId(rs.getInt("id"));
                // 对name属性赋值
                p.setName(rs.getString("name"));
                // 对num属性赋值
                p.setNum(rs.getInt("num"));
                // 对price属性赋值
                p.setPrice(rs.getDouble("price"));
                // 对unit属性赋值
                p.setUnit(rs.getString("unit"));
                // 将Product添加到List集合中
                list.add(p);
            }
            // 关闭ResultSet
            rs.close();
            // 关闭PreparedStatement
            ps.close();
            // 关闭Connection
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 查询总记录数
     * @return 总记录数
     */
    public int findCount(){
        // 总记录数
        int count = 0;
        // 获取数据库连接
        Connection conn = getConnection();
        // 查询总记录数SQL语句
        String sql = "select count(*) from tb_product";
        try {
            // 创建Statement
            Statement stmt = conn.createStatement();
            // 查询并获取ResultSet
            ResultSet rs = stmt.executeQuery(sql);
            // 光标向后移动,并判断是否有效
            if(rs.next()){
                // 对总记录数赋值
                //rs.getInt()方法,通过索引或者列名来获得查询结果集中的某一列的值
                count = rs.getInt(1);
            }
            // 关闭ResultSet
            rs.close();
            // 关闭Connection
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        // 返回总记录数
        return count;
    }
}

(3)创建FindServlet类,实现获取分页查询结果及构造分页条对象。其中获取分页查询结果,通过调用BookDao类中的find()方法,并传递所要查询的页码就可以获取;分页条对象是JSP页面中的分页条,用于显示商品信息的页码,程序中主要通过创建页码的超链接,然后组合字符串进行构造:

package com.megustas.servlet;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.megustas.bean.Product;
import com.megustas.bean.BookDao;

/**
 * Servlet implementation class FindServlet
 */
public class FindServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;


    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 当前页码
        int currPage = 1;
        // 判断传递页码是否有效
        if(request.getParameter("page") != null){
            // 对当前页码赋值
            currPage = Integer.parseInt(request.getParameter("page"));
        }
        // 实例化ProductDao
        BookDao dao = new BookDao();
        // 查询所有商品信息
        List<Product> list = dao.find(currPage);
        // 将list放置到request之中
        request.setAttribute("list", list);
        // 总页数
        int pages ;
        // 查询总记录数
        int count = dao.findCount();
        // 计算总页数
        if(count % Product.PAGE_SIZE == 0){
            // 对总页数赋值
            pages = count / Product.PAGE_SIZE;
        }else{
            // 对总页数赋值
            pages = count / Product.PAGE_SIZE + 1;
        }
        // 实例化StringBuffer
        StringBuffer sb = new StringBuffer();
        // 通过循环构建分页条
        for(int i=1; i <= pages; i++){
            // 判断是否为当前页
            if(i == currPage){
                // 构建分页条
                sb.append("『" + i + "』");
            }else{
                // 构建分页条
                sb.append("<a href='FindServlet?page=" + i + "'>" + i + "</a>");
            }
            // 构建分页条
            sb.append(" ");
        }
        // 将分页条的字符串放置到request之中
        request.setAttribute("bar", sb.toString());
        // 转发到product_list.jsp页面
        request.getRequestDispatcher("product_list.jsp").forward(request, response);
    }

}

(4)web层进行显示

主界面:

<body>
    <a href="FindServlet">查看所有商品信息</a>
</body>

商品显示界面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<%@page import="java.util.List"%>
<%@page import="com.megustas.bean.Product"%><html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>所有商品信息</title>
<style type="text/css">
    td{font-size: 12px;}
    h2{margin: 0px}
</style>
</head>
<body>
<table align="center" width="450" border="1" height="180" bordercolor="white" bgcolor="black" cellpadding="1" cellspacing="1">
    <tr bgcolor="white">
        <td align="center" colspan="5">
            <h2>所有商品信息</h2>
        </td>
    </tr>
    <tr align="center" bgcolor="#e1ffc1" >
        <td><b>ID</b></td>
        <td><b>商品名称</b></td>
        <td><b>价格</b></td>
        <td><b>数量</b></td>
        <td><b>单位</b></td>
    </tr>
    <%
        List<Product> list = (List<Product>)request.getAttribute("list");
        for(Product p : list){
    %>
    <tr align="center" bgcolor="white">
        <td><%=p.getId()%></td>
        <td><%=p.getName()%></td>
        <td><%=p.getPrice()%></td>
        <td><%=p.getNum()%></td>
        <td><%=p.getUnit()%></td>
    </tr>
    <%  
        }
    %>
    <tr>
        <td align="center" colspan="5" bgcolor="white">
            <%=request.getAttribute("bar")%>
        </td>
    </tr>
</table>
</body>
</html>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值