欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java开发中使用Servlet实现分页

程序员文章站 2022-03-25 15:03:25
本次分页功能的实现使用了servlet+jsp+mysql【搬运自我的博客:创建于2020-06-22 17:29】一、实现前的准备1.本次分页我们使用MVC三层架构进行实现如果对mvc框没有了解,请移步我的另一篇博客MVC三层架构在Java项目中的应用2.项目结构如下3.c3p0连接池:C3P0Util.java、c3p0-config.xml数据库连接池工具包-C3P0Util.java/** * @author Zhao Wen * @date 2020年6月5日上午...

本次分页功能的实现使用了servlet+jsp+mysql


一、实现前的准备

1.本次分页我们使用MVC三层架构进行实现

如果对mvc框没有了解,请移步我的另一篇博客MVC三层架构在Java项目中的应用


2.项目结构如下
Java开发中使用Servlet实现分页


3.c3p0连接池:C3P0Util.java、c3p0-config.xml

数据库连接池工具包-C3P0Util.java

/**
 * @author Zhao Wen
 * @date 2020年6月5日上午10:40:42
 * @filename C3P0Util.java
 * @details C3P0连接池工具包
 */ public class C3P0Util { private static ComboPooledDataSource dataSource = new ComboPooledDataSource("zhaowen"); public static ComboPooledDataSource getDataSource(){ return dataSource; } public static Connection getConnection(){ try { return (Connection) dataSource.getConnection(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } public static void release(Connection conn,Statement stmt,ResultSet rs){ if(rs!=null){ try { rs.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } rs=null; } if(stmt!=null){ try { stmt.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } stmt=null; } if(conn!=null){ try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } conn=null; } } public static void release(Connection conn,PreparedStatement ps,ResultSet rs){ if(rs!=null){ try { rs.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } rs=null; } if(ps!=null){ try { ps.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } ps=null; } if(conn!=null){ try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } conn=null; } } public static void release(Connection conn){ if(conn!=null){ try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } conn=null; } } } 

数据库里连接池配置文件-c3p0-config.xml(需要自行修改jdbcUrluserpassword属性值)

<?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <default-config> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl"> jdbc:mysql://localhost:3306/student </property> <property name="user">root</property> <property name="password">666666</property> <property name="checkoutTimeout">30000</property> <property name="initialPoolSize">10</property> <property name="maxIdleTime">30</property> <property name="maxPoolSize">100</property> <property name="minPoolSize">10</property> <property name="maxStatements">200</property> </default-config> <!-- 本次连接使用配置 --> <named-config name="zhaowen"> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl"> jdbc:mysql://localhost:3306/student </property> <property name="user">root</property> <property name="password">666666</property> <property name="initialPoolSize">5</property> <property name="maxPoolSize">50</property> </named-config> </c3p0-config> 

对于数据库连接池有疑问的可以查看我另一篇博客数据库连接池c3p0、dbcp和dbutils工具类的使用



二、后端实现

分页JavaBean:PageBean.java

说明:分页JavaBean,存储分页信息,方便在Web层显示

 private List<T> stuInfoList = new ArrayList<>(); // 每页显示信息List,此处使用泛型可提高代码复用率 private int currentPage; // 当前浏览页 private int currentCount; // 当前页显示条数 private int totalPage; // 总页数 private int totalCount; // 信息总条数 


分页Servlet:PageShowServlet.java

说明:控制器 Servlet层,接收用户请求,调用service层分页功能实现代码获取数据,跳转(转发)页面

 PageShowService stuinfoService = new PageShowService(); PageBean pageBean = null; String cp = request.getParameter("currentPage"); int currentPage = 1; if (cp != null) { Integer cpInt = Integer.valueOf(cp); if (cpInt != -1) { currentPage = cpInt; // 当前浏览页数 } } int currentCount = 20; // 每页显示信息数 try { pageBean = stuinfoService.findPageBean(currentPage, currentCount); } catch (SQLException e) { e.printStackTrace(); System.out.print("分页信息查找失败"); } 

此处通过前端页面传送的参数CurrentPage,来获知具体请求的页数;再通过调用Service方法中的findPageBean()方法,来获取分页数据。



分页Service:PageShowService.java

说明:给servlet层提供分页查询功能方法调用,调用Dao层数据分页方法查询获取数据

public PageBean findPageBean(int currentPage, int currentCount) throws SQLException { PageBean<Userinfo> pageBean = new PageBean<>(); StuInfoDao stuInfoDaoImpl = new StuInfoDaoImpl(); pageBean.setCurrentPage(currentPage); pageBean.setCurrentCount(currentCount); int totalCount = stuInfoDaoImpl.getTotalCount(); int totalPage = (int) Math.ceil(1.0 * totalCount / currentCount); pageBean.setTotalPage(totalPage); pageBean.setTotalCount(stuInfoDaoImpl.getTotalCount()); // 分段获取用户信息 int index = (currentPage - 1) * currentCount; pageBean.setStuInfoList(stuInfoDaoImpl.findStuListForPageBean(index, currentCount)); return pageBean; } 
  • 使用PageBean.java中的getter/setter方法,对分页属性进行封装,其中信息列表(stuinfoList)和信息总条数(totalcount),必须要在调用Dao实现类查询;


  • 而信息总页数,需要根据每页显示数(CurrentCount)和信息总数(stuinfoList)来判断,所以此处我们使用公式

总页数(totalPage)=Math.ceil(总条数  /当前显示的条数)【非四舍五入,应前进】 

转换为Java代码就是

int totalPage = Math.ceil(totalCount/currentCount) 

  • 每次调用分页数据时,为了准确获取到指定数据,我们需要一个值,来在分段查询时作为一个初始值。

    此处我们使用index来表示,而index的计算公式如下:

    index=(当前页数currentPage-1)*每页显示的条数(currentCount) 

    转换为Java代码就是

    int index = (currentPage - 1) * currentCount; 

    index值会随着当前浏览页数和每一页显示条数限制:

    例如,当每页限制显示4条时,inde值变化情况如下:

页数 开始索引 每页显示条数
1 0 4
2 4 4
3 8 4
4 12 4


分页Dao:StuInfoDaoImpl.java

说明:给Service层提供分页功能方法,直接接触数据库(一般使用DBUtils封装的工具类操作数据库/一般 作为抽象接口,新建 xxDaoImpl对其进行实现)


获取指定表的记录总数:getTotalCount()

 public int getTotalCount() throws SQLException { String sql = "select count(*) from userInfo"; Long count = new QueryRunner(dataSource).query(sql, new ScalarHandler<>()); return count.intValue(); } 

获取分页数据列表:findStuListForPageBean(int index,int currentCount)

 public List<Userinfo> findStuListForPageBean(int index, int currentCount) throws SQLException { String sql = "select sno,name,age,score from userInfo limit ? , ?"; List<Userinfo_0134> stuInfoList = new QueryRunner(dataSource).query(sql, new BeanListHandler<>(Userinfo), index, currentCount); return stuInfoList; } 

此处使用limit关键字,通过每次调用参数index和currentCount的值,来获取指定区段的数据。


三、前端界面

分页显示页面:page_list.jsp

说明:使用JSTL的c:forEach标签遍历分页数据,在前台进行展示

显示页面

 <!-- 信息展示 -->
		<table border="1">
			<tr>
				<td>学号</td>
				<td>姓名</td>
				<td>年龄</td>
				<td>成绩</td>
			</tr>
			<c:forEach items="${pageBean.stuInfoList}" var="stuinfo">
				<tr>
					<td>${stuinfo.sno}</td>
					<td>${stuinfo.name}</td>
					<td>${stuinfo.age}</td>
					<td>${stuinfo.score}</td>
				</tr>
			</c:forEach>
		</table>
		<p>----------------------------------------------------------------------------</p> 

显示分页数据:当前浏览页、总页数、总信息条数

<div>
	<span>当前页:${pageBean.currentPage}/${pageBean.totalPage}</span>
    | 
    <span>总页数:${pageBean.totalPage}</span>
    |
    <span>总信息数:${pageBean.totalCount}</span>
</div> 

显示分页页码:页码、前一页、后一页实现

<div>
    <!--首页-->
	<span><a href="${pageContext.request.contextPath}/PageShowServlet_0134?		   currentPage=1">首页</a>
    </span>
    ||
    <!--前一页-->
    <span><a href="${pageContext.request.contextPath}/PageShowServlet?currentPage=${pageBean.currentPage - 1}">上一页</a>
    </span>
    <!--页码-->
	<c:forEach begin="1" end="${pageBean.totalCount/20+1}" var="pageCount">
	|
	<a href="${pageContext.request.contextPath}/PageShowServlet?currentPage=${pageCount}">${pageCount}</a>
	|
     </c:forEach>
    |
    <!--后一页-->
    <span><a href="${pageContext.request.contextPath}/PageShowServlet?currentPage=${pageBean.currentPage + 1}">下一页</a>
    </span>
	|
    <!--尾页-->
    <span><a 
             <fmt:formatNumber var="lastPage" value="${pageBean.totalCount/20+1}" pattern="#" />
			href="${pageContext.request.contextPath}/PageShowServlet?currentPage=${lastPage - 1}">尾页</a>
    </span>
</div> 

四、总结

要使用Servlet完成分页,我们首先要定义JavaBean用于数据封装、然后依次编写Dao数据库DDL语句、分页Servlet用于与前端交互,最后再编写前端页面并使用EL表达式接收数据并显示。

本文地址:https://blog.csdn.net/qq_43795348/article/details/108861650