分页

分页技术

2016/12/23

分页介绍

主要用在当页面上数据非常多的时候,不能在一个页面上全部显示。需要把页面上的数据分成好多子页面来显示。

例如:使用百度进行搜索,搜索的结果会很多,百度将所有的结果分成若干也进行显示。在每页的底部会有如下显示。
image

用户可以选择相应的数字,跳转到对应的页面查看搜索的信息。


本人编写的分页条使用的技术有:struts2框架,DButils,c3p0连接池

分页思路流程

页面 ----> servlet/action ----> service ----> dao

页面 <---- servlet/action <---- service <---- dao

  • 思路:

    1.页面传递给servlet/action 参数:pageCode

    2.servlet/action获取到pageCode.再传递给Service, 最终servlet/action把PageBean传递给页面

    3.Service通过dao层的方法获取总记录数和每页的记录数据进行处理,最终把封装好的PageBean返回给servlet/action

    4.页面通过后台传过的数据用s标签或者EL表达式获取数据进行展示

分页最后的效果

第N页/共M页 首页 上一页 1 2 3 4 5 6 7 8 9 10 下一页 尾页 口—>下拉框

对页面进行分析

  • 根据以上的效果分析出需要的条件:

    1.当前页码 (pageCode)

      pageCode是由page.jsp页面提供
    

    2.总页数 (totalPage)

      总页数是由总记录数和每页记录数计算得到的,公式:总页数=总记录数%每页记录数 ==0 ? 总记录数/每页记录数 : 总记录数/每页记录数 + 1
    

    3.总记录数 (totalRecord)

      总记录数是由查询数据库得到的 , select count(*) from user;
    

    4.每页记录数 (pageSize)

      每页记录数是由自己设定的
    

    5.当前页记录 (datas)

      当前页记录是由查数据库得到 ,select * from user limit (pageCode-1) * pageSize,pageSize;
    

1). 得到这些分页的数据把它们封装到一个javaBean中,命名为PageBean.java

PageBean.java

package fenye;
import java.util.List;
public class PageBean<T> {
private int pageCode;// 当前页码
// private int totalPage;// 总页数
private List<T> datas;// 当前页的记录
private int totalRecord;// 总记录
private int pageSize = 10;// 每页记录数

public PageBean() {
}
public PageBean(int pageCode, int totalRecord) {
	this(pageCode, totalRecord, 10);
}
public PageBean(int pageCode, int totalRecord, int pageSize) {
	this.pageCode = pageCode;
	this.totalRecord = totalRecord;
	this.pageSize = pageSize;
}
public int getPageCode() {
	return pageCode;
}
public void setPageCode(int pageCode) {
	this.pageCode = pageCode;
}
public List<T> getDatas() {
	return datas;
}
public void setDatas(List<T> datas) {
	this.datas = datas;
}
public int getTotalRecord() {
	return totalRecord;
}
public void setTotalRecord(int totalRecord) {
	this.totalRecord = totalRecord;
}
public int getPageSize() {
	return pageSize;
}
public void setPageSize(int pageSize) {
	this.pageSize = pageSize;
}
public int getTotalPage() {
	// 计算totalPage
	int totalPage = this.totalRecord / pageSize;
	return totalRecord % pageSize == 0 ? totalPage : totalPage + 1;
}
}

2). servlet/action层给Service层传递pageCode,然后再Service层进行各种业务的处理完成对PageBean的创建与封装,最后返回给servlet/action

  • service层还要依赖dao层提供一些方法:

    1.查询记录数的方法(count())

    2.查询当前页的记录(queryByPage())

  • dao层使用c3p0连接池进行连接来操作数据库,

配置c3p0-config.xml

<c3p0-config>
  	<default-config>
	    <property name="driverClass">com.mysql.jdbc.Driver</property>
	    <property name="jdbcUrl">jdbc:mysql://localhost:3306/page</property>
	    <property name="user">root</property>
	    <property name="password">abc</property>
  	</default-config>
</c3p0-config>
  • 提供数据库连接池 和数据库连接的工具类 JDBCUtils.java

JDBCUtils.java

package utils;

import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
/**
 * 工具类 提供数据库连接池 和数据库连接
 * 
 */
public class JDBCUtils {
	private static DataSource dataSource = new ComboPooledDataSource();
	public static DataSource getDataSource() {
		return dataSource;
	}
	/**
	 * 当DBUtil需要手动控制事务时,调用该方法获得一个连接
	 * 
	 * @return
	 * @throws SQLException
	 */
	public static Connection getConnection() throws SQLException {
		return dataSource.getConnection();
	}
}
  • dao层创建一个类 ,命名为:PageDao.java

PageDao.java

package fenye;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.apache.commons.lang3.StringUtils;
import utils.JDBCUtils;

public class PageDao {
	private QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource());

	/**
	 * 查询总记录数
	 * 
	 */
	public int count(User user) {
		String sql = "select count(*) from user where 1=1";
		List<Object> list = new ArrayList<Object>();
		if (StringUtils.isNotBlank(user.getUsername())) {
			sql += " and username like ?";
			list.add("%" + user.getUsername() + "%");
		}
		if (StringUtils.isNotBlank(user.getSex())) {
			sql += " and sex = ?";
			list.add(user.getSex());
		}
		// System.out.println(sql);
		try {
			Number number = (Number) queryRunner.query(sql, new ScalarHandler(), list.toArray());
			return number.intValue();
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException("查询总记录数失败");
		}
	}

	/**
	 * 分页查询
	 * 
	 */
	public List<User> queryByPage(User user, int offset, int len) {
		String sql = "select * from user where 1=1";
		List<Object> list = new ArrayList<Object>();
		if (StringUtils.isNotBlank(user.getUsername())) {
			sql += " and username like ?";
			list.add("%" + user.getUsername() + "%");
		}
		if (StringUtils.isNotBlank(user.getSex())) {
			sql += " and sex = ?";
			list.add(user.getSex());
		}
		sql += " limit ?, ?";
		list.add(offset);
		list.add(len);
		// System.out.println(sql);
		try {
			return queryRunner.query(sql, new BeanListHandler<User>(User.class), list.toArray());
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException("分页查询失败");
		}
	}
}

3). service层接受servlet/action传过的User对象和pageCode参数来处理业务封装PageBean对象 然后返回给servlet/action

User.java

package fenye;
public class User {
	private int id;
	private String username;
	private String password;
	private String sex;	
	public int getId() {
		return id;
	}	
	public void setId(int id) {
		this.id = id;
	}	
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", password=" + password + ", sex=" + sex + "]";
	}
}

PageService.java

package fenye;
import java.util.List;

public class PageService {
	private PageDao pageDao = new PageDao();

	public PageBean<User> queryByBean(User user, int pageCode) {
		// 获取总记录数
		int totalRecord = pageDao.count(user);
		// 使用当前页码和总记录数创建PageBean
		PageBean<User> pageBean = new PageBean<User>(pageCode, totalRecord);
		// 查询本页记录
		List<User> datas = pageDao.queryByPage(user, (pageCode - 1) * pageBean.getPageSize(), pageBean.getPageSize());
		// 保存pageBean中
		pageBean.setDatas(datas);
		// 返回pageBean
		return pageBean;
	}
}

4). servlet/action层接受service层返回的PageBean对象,将其保存在域中或值栈中反馈给page.jsp页面

UserACtion.java

package fenye;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;	
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

public class UserAction extends ActionSupport implements ModelDriven<User> {
	private User user = new User();

	@Override
	public User getModel() {
		return user;
	}
	public String page() throws Exception {
		HttpServletRequest request = ServletActionContext.getRequest();
		HttpServletResponse response = ServletActionContext.getResponse();
		PageQuery pageQuery = new PageQuery();
		pageQuery.query(request, response, user);
		return "page";
	}
}

PageQuery.java

package fenye;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.ServletActionContext;

public class PageQuery {
	public String query(HttpServletRequest request, HttpServletResponse response, User user) throws ServletException, IOException {
		/*
		 * 创建超链接的条件
		 * 因为表单提交会请求本方法
		 * 因为在分页的导航条中的超链接,也要请求本方法
		 * 但在分页的超链接中没有条件,这会变成查询所有,而不是条件查询
		 * 所以必须把条件传递到页面上
		 */	
		StringBuilder sb = new StringBuilder();
		String username = user.getUsername();
		if (StringUtils.isNotBlank(user.getUsername())) {
			if (request.getMethod().equalsIgnoreCase("get")) {
				username = new String(username.getBytes("iso-8859-1"), "utf-8");
				user.setUsername(username);
			}
			sb.append("&username=").append(username);
		}
		String sex = user.getSex();
		if (StringUtils.isNotBlank(user.getSex())) {
			if (request.getMethod().equalsIgnoreCase("get")) {
				sex = new String(sex.getBytes("iso-8859-1"), "utf-8");
				user.setSex(sex);
			}
			sb.append("&sex=").append(sex);
		}
		// System.out.println(sb.toString());
		ServletActionContext.getContext().put("url", sb.toString());

		int pageCode = 1;
		String s = request.getParameter("pageCode");
		if (s != null && !s.trim().isEmpty()) {
			pageCode = Integer.parseInt(s);
		}
		PageService pageService = new PageService();
		PageBean<User> UserList = pageService.queryByBean(user, pageCode);
		ServletActionContext.getContext().put("UserList", UserList);
		return "true";
	}
}

5). 在工程的src下配置struts2的配置文件struts.xml

配置struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <constant name="struts.devMode" value="true" />
	<constant name="struts.ui.theme" value="simple"/>
    <package name="default" namespace="/" extends="struts-default">
		<action name="user_*" class="fenye.UserAction" method="{1}">
			<result name="page">/page.jsp</result>
		</action>     
    </package>
</struts>

配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<display-name>Struts2</display-name>
<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<welcome-file-list>
    <welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>

6). 页面:

使用的是c标签:

<%@taglib prefix="c"  uri="http://java.sun.com/jsp/jstl/core"%>	
<c:set var="root" value="${pageContext.request.contextPath}"/>

page.jsp—分页条的代码

<!-- 主要完成根据指定的内容查询相应的联系人 -->
<div>
<form action="${pageContext.request.contextPath}/user_page" method="post">
	<table>
		<tr>
			<td align="center">根据指定的信息查询</td>
		</tr>
		<tr>
			<td>用户名</td>
			<td><input type="text" name="username"/></td>	
			<td>性别</td>
			<td><input type="text" name="sex"/></td>
		</tr>
		<tr>
			<td>
				<input type="submit" value="查询"/>
			</td>
		</tr>
	</table>
</form>
</div>


<!-- 完成显示功能 -->
<div>
<table border="1" cellpadding="5" cellspacing="0" width="300px">
	<tr>
		<td>id</td>
		<td>用户名</td>
		<td>密码</td>
		<td>性别</td>
	</tr>
	<s:iterator value="#UserList.datas" var="user">
	<tr>
		<td>
		<s:property value="#user.id"/>
		</td>
		<td>
		<s:property value="#user.username"/>
		</td>
		<td>
		<s:property value="#user.password"/>
		</td>
		<td>
		<s:property value="#user.sex"/>
		</td>
	</tr>
	</s:iterator>
</table>

<!-- 分页的实现 -->	
    		    	
第${UserList.pageCode}页/共${UserList.totalPage}页
<a href="${root}/user_page?pageCode=1${url}">首页</a>
<c:if test="${UserList.pageCode > 1}">
<a href="${root}/user_page?pageCode=${UserList.pageCode - 1}${url}">上一页</a>
</c:if>
    	
<!-- 页码列表 -->
<c:set var="begin" value="1"/>
<c:set var="end" value="10"/>

<!-- 定位begin和end -->
<c:choose>
	<c:when test="${UserList.totalPage <= 10}">
		<c:set var="begin" value="1"/>
		<c:set var="end" value="${UserList.totalPage}"/>
	</c:when>
	<c:otherwise>
		<c:choose>
			<c:when test="${UserList.pageCode - 4 < 1}">
				<c:set var="begin" value="1"/>
				<c:set var="end" value="10"/>
			</c:when>
			<c:when test="${UserList.pageCode + 5 > UserList.totalPage}">
				<c:set var="begin" value="${UserList.totalPage - 9}"/>
				<c:set var="end" value="${UserList.totalPage }"/>
			</c:when>
			<c:otherwise>
				<c:set var="begin" value="${UserList.pageCode - 4}"/>
				<c:set var="end" value="${UserList.pageCode + 5 }"/>
			</c:otherwise>
		</c:choose>
	</c:otherwise>
</c:choose>

<c:forEach begin="${begin}" end="${end}" var="i">
	<c:choose>
		<c:when test="${UserList.pageCode eq i}">${i}</c:when>
		<c:otherwise>
			<a href="${root}/user_page?pageCode=${i}${url}">[${i}]</a>					
		</c:otherwise>
	</c:choose>
</c:forEach>

<c:if test="${UserList.pageCode < UserList.totalPage}">
	<a href="${root}/user_page?pageCode=${UserList.pageCode + 1}${url}">下一页</a>
</c:if>
	<a href="${root}/user_page?pageCode=${UserList.totalPage}${url}">尾页</a>

<!-- 下拉列表 -->
<select name="pageCode" onchange="_go(this)">
	<c:forEach begin="1" end="${UserList.totalPage}" var="i">
		<option value="${i}" <c:if test="${UserList.pageCode eq i}">selected='selected'</c:if>>${i}</option>
	</c:forEach>
</select>
</div>

<!--分页条使用到的js-->
<script type="text/javascript">
	function _go(select){
		var index = select.selectedIndex;//选中的option的下标
		var option = select.options[index];//通过下标得到option元素的对象
		var value = option.value;//通过option元素对象得到value值
		location="${root}/user_page?pageCode="+value+"${url}";
	}
</script>

  • 仅供参考,欢迎大家指出错误!!!
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值