servlet+jsp实现分页查询+导出
2016-03-16 14:18
615 查看
为一个10年前的项目添加一些新功能,当时项目用的技术是servlet+jdk1.4,而且项目中并没有分页以及导出EXCEL功能,所以我加了这两个功能。首相我想的是,因为查询的数据要通过很多个表,其中有三个表的数据量特别大,而且都需要全表扫描,加了索引之后SQL执行速度依然不是很快,所以当时想用JS来控制分页,这样只需要与数据库进行一次交互,用JS分页我参考了一个例子
js demo:
JSP demo:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<script type="text/javascript" language="javascript">
window.onload = function() {
page = new Page(3, 'table1', 'group_one');
};
</script>
<script type="text/javascript" language="javascript" src="fenye.js">
</script>
</head>
<body>
<table id="table1" border="0" width="486">
<thead>
<tr style="background-color:#CCCCCC;">
<th style="cursor:pointer;">Last Name</th>
<th style="cursor:pointer;">First Name</th>
<th style="cursor:pointer;">Birthday</th>
<th style="cursor:pointer;">Siblings</th>
</tr>
</thead>
<tbody id="group_one">
<tr style="background-color:#f3f3f3">
<td>Smith</td>
<td>John</td>
<td>7/12/1978</td>
<td>2</td>
</tr>
<tr style="background-color:#B4D6FC">
<td>Johnson</td>
<td>Betty</td>
<td>10/15/1977</td>
<td>4</td>
</tr>
<tr style="background-color:#f3f3f3">
<td>Henderson</td>
<td>Nathan</td>
<td>2/25/1949</td>
<td>1</td>
</tr>
<tr style="background-color:#B4D6FC">
<td>Williams</td>
<td>James</td>
<td>7/8/1980</td>
<td>4</td>
</tr>
<tr style="background-color:#f3f3f3">
<td>Gilliam</td>
<td>Micheal</td>
<td>7/22/1949</td>
<td>1</td>
</tr>
<tr style="background-color:#f3f3f3">
<td>Smith</td>
<td>John</td>
<td>7/12/1978</td>
<td>2</td>
</tr>
<tr style="background-color:#B4D6FC">
<td>Johnson</td>
<td>Betty</td>
<td>10/15/1977</td>
<td>4</td>
</tr>
<tr style="background-color:#f3f3f3">
<td>Henderson</td>
<td>Nathan</td>
<td>2/25/1949</td>
<td>1</td>
</tr>
<tr style="background-color:#B4D6FC">
<td>Williams</td>
<td>James</td>
<td>7/8/1980</td>
<td>4</td>
</tr>
<tr style="background-color:#f3f3f3">
<td>Gilliam</td>
<td>Micheal</td>
<td>7/22/1949</td>
<td>1</td>
</tr>
</tbody>
</table>
<span id="s"></span>
<table>
<tr>
<td><a href="#" onclick="page.firstPage();">首页</a></td>
<td><a href="#" onclick="page.prePage();">上一页</a></td>
<td>第<span id="pageindex">1</span>页</td>
<td><a href="#" onclick="page.nextPage();">下一页</a></td>
<td><a href="#" onclick="page.lastPage();">尾页</a></td>
<td>第<select id="pageselect" onchange="page.changePage();"></select>页</td>
</tr>
</table>
</body>
</html>
后来实现了效果之后,发现数据量过多(10000+条)后用前台拼table这种方式会导致网页加载变得异常慢,所以就用后台分页的方法重做了一次分页功能
首先需要建一个page类,存放分页的信息
public class Pager {
private int pageIndex;//第几页
private int pageSize;//一页显示多少行
private int totalRecord;//总共多少条记录
private int totalPage;//总共多少页
private List datas;//存放数据
public int getPageIndex() {
return pageIndex;
}
public void setPageIndex(int pageIndex) {
this.pageIndex = pageIndex;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalRecord() {
return totalRecord;
}
public void setTotalRecord(int totalRecord) {
this.totalRecord = totalRecord;
}
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public List getDatas() {
return datas;
}
public void setDatas(List datas) {
this.datas = datas;
}
}
查询的时候将分页信息传入sql中:
int start = (pageIndex-1)*pageSize;
String sql = "select * from (SQL语言) a where rownum<=start+pageSize) where num>start
这样就查询出了分页的信息
在前台展示分页即可,前台需要定义一个int pageSize = 20;//每页显示多上行数据
int pageIndex = 1;//页数
这里只记录前台分页的代码块
<%if(pager!=null){%>
<table>
<tr>
<td>
<%
String url = "CMCCBoardBandHisQuery?OprType=CMCCBoardBandHisQuery";
url += "&accept_start_date="+accept_start_date+" 00:00:00";
url += "&accept_end_date="+ accept_end_date +" 23:59:59";
url += "&station_kind=" + station_kind;
url += "&pageSize=" + pageSize;
url += "&pageIndex=";
%>
第<%= pageIndex %>页,共<%= pager.getTotalPage() %>页
<%
if (pageIndex > 1){
%>
<a href="<%=url+1 %>">首页</a>
<a href="<%=url+(pageIndex-1) %>">上一页</a>
<%
}else {
%>
首页 上一页
<%}%>
<%
if (pageIndex < pager.getTotalPage()){
%>
<a href="<%=url+(pageIndex+1) %>">下一页</a>
<a href="<%=url+pager.getTotalPage() %>">尾页</a>
<%
}else {
%>
下一页 尾页
<%}%>
跳转至第
<label>
<select id="page" name="page" onchange="redirect();">
<%
for ( int i = 1; i <= pager.getTotalPage(); i++){
if (i == pageIndex){
%>
<!--当前页页码默认选中-->
<option selected value="<%= i%>"><%= i %></option>
<%
}else {
%>
<option value="<%= i %>"><%= i %></option>
<%
}
}%>
</select>
</label> 页
</td>
</tr>
</table>
<%} %>
这样就完成了分页效果,优点是前台一次性不用加载过多的table,网页加载速度变快,缺点是每次点上一页,下一页等都会完成一次与数据库的交互,大家依情况自己选择吧。
js demo:
// JavaScript Document /**//** * js分页类 * * @param iAbsolute * 每页显示记录数 * @param sTableId * 分页表格属性ID值,为String * @param sTBodyId * 分页表格TBODY的属性ID值,为String,此项为要分页的主体内容 * @Version 1.0.0 * @author 辛现宝 2007-01-15 created var __variable__; private function * __method__(){};private */ window.document.onkeydown = disableRefresh; function disableRefresh(evt) { evt = (evt) ? evt : window.event if (evt.keyCode) { if (evt.keyCode == 116) { //do something page.firstPage(); } } }; function Page(iAbsolute, sTableId, sTBodyId) { this.absolute = iAbsolute; // 每页最大记录数 this.tableId = sTableId; this.tBodyId = sTBodyId; this.rowCount = 0;// 记录数 this.pageCount = 0;// 页数 this.pageIndex = 0;// 页索引 this.__oTable__ = null;// 表格引用 this.__oTBody__ = null;// 要分页内容 this.__dataRows__ = 0;// 记录行引用 this.__oldTBody__ = null; this.__init__(); // 初始化; }; /**//* * 初始化 */ Page.prototype.__init__ = function() { this.__oTable__ = document.getElementById(this.tableId);// 获取table引用 this.__oTBody__ = this.__oTable__.tBodies[this.tBodyId];// 获取tBody引用 this.__dataRows__ = this.__oTBody__.rows; this.rowCount = this.__dataRows__.length; try { this.absolute = (this.absolute <= 0) || (this.absolute > this.rowCount) ? this.rowCount : this.absolute; this.pageCount = parseInt(this.rowCount % this.absolute == 0 ? this.rowCount / this.absolute : this.rowCount / this.absolute + 1); } catch (exception) { } this.__LoadPages__(); this.__updateTableRows__(); }; /**//* * 下一页 */ Page.prototype.nextPage = function() { if (this.pageIndex + 1 < this.pageCount) { this.pageIndex += 1; this.__updateTableRows__(); } document.getElementById("pageindex").innerHTML = this.pageIndex + 1; document.getElementById("pageselect").value = this.pageIndex + 1; }; /**//* * 上一页 */ Page.prototype.prePage = function() { if (this.pageIndex >= 1) { this.pageIndex -= 1; this.__updateTableRows__(); } document.getElementById("pageindex").innerHTML = this.pageIndex + 1; document.getElementById("pageselect").value = this.pageIndex + 1; }; /**//* * 首页 */ Page.prototype.firstPage = function() { if (this.pageIndex != 0) { this.pageIndex = 0; this.__updateTableRows__(); } document.getElementById("pageindex").innerHTML = this.pageIndex + 1; document.getElementById("pageselect").value = this.pageIndex + 1; }; /**//* * 尾页 */ Page.prototype.lastPage = function() { if (this.pageIndex + 1 != this.pageCount) { this.pageIndex = this.pageCount - 1; this.__updateTableRows__(); } document.getElementById("pageindex").innerHTML = this.pageCount; document.getElementById("pageselect").value = this.pageIndex + 1; }; /**//* * 页定位方法 */ Page.prototype.aimPage = function(iPageIndex) { if (iPageIndex > this.pageCount - 1) { this.pageIndex = this.pageCount - 1; } else if (iPageIndex < 0) { this.pageIndex = 0; } else { this.pageIndex = iPageIndex; } this.__updateTableRows__(); }; Page.prototype.changePage = function() { var iPageIndex = document.getElementById("pageselect").value; this.aimPage(iPageIndex - 1); document.getElementById("pageindex").innerHTML = iPageIndex; }; /**//* * 执行分页时,更新显示表格内容 */ Page.prototype.__updateTableRows__ = function() { var iCurrentRowCount = this.absolute * this.pageIndex; var iMoreRow = this.absolute + iCurrentRowCount > this.rowCount ? this.absolute + iCurrentRowCount - this.rowCount : 0; var tempRows = this.__cloneRows__(); // alert(tempRows === this.dataRows); // alert(this.dataRows.length); var removedTBody = this.__oTable__.removeChild(this.__oTBody__); var newTBody = document.createElement("TBODY"); newTBody.setAttribute("id", this.tBodyId); for ( var i = iCurrentRowCount; i < this.absolute + iCurrentRowCount - iMoreRow; i++) { newTBody.appendChild(tempRows[i]); } this.__oTable__.appendChild(newTBody); /**//* * this.dataRows为this.oTBody的一个引用, 移除this.oTBody那么this.dataRows引用将销失, * code:this.dataRows = tempRows;恢复原始操作行集合. */ this.__dataRows__ = tempRows; this.__oTBody__ = newTBody; // alert(this.dataRows.length); // alert(this.absolute+iCurrentRowCount); // alert("tempRows:"+tempRows.length); }; /**//* * 克隆原始操作行集合 */ Page.prototype.__cloneRows__ = function() { var tempRows = []; for ( var i = 0; i < this.__dataRows__.length; i++) { /**//* * code:this.dataRows[i].cloneNode(param), param = 1 or * true:复制以指定节点发展出去的所有节点, param = 0 or false:只有指定的节点和它的属性被复制. */ tempRows[i] = this.__dataRows__[i].cloneNode(1); } return tempRows; }; //add by youngt 13/05/23 Page.prototype.__LoadPages__ = function() { //alert(this.pageCount); document.getElementById("pageselect").options.length = 0; for ( var i = 1; i <= this.pageCount; i++) { document.getElementById("pageselect").options.add(new Option(i, i)); } }; //add end
JSP demo:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<script type="text/javascript" language="javascript">
window.onload = function() {
page = new Page(3, 'table1', 'group_one');
};
</script>
<script type="text/javascript" language="javascript" src="fenye.js">
</script>
</head>
<body>
<table id="table1" border="0" width="486">
<thead>
<tr style="background-color:#CCCCCC;">
<th style="cursor:pointer;">Last Name</th>
<th style="cursor:pointer;">First Name</th>
<th style="cursor:pointer;">Birthday</th>
<th style="cursor:pointer;">Siblings</th>
</tr>
</thead>
<tbody id="group_one">
<tr style="background-color:#f3f3f3">
<td>Smith</td>
<td>John</td>
<td>7/12/1978</td>
<td>2</td>
</tr>
<tr style="background-color:#B4D6FC">
<td>Johnson</td>
<td>Betty</td>
<td>10/15/1977</td>
<td>4</td>
</tr>
<tr style="background-color:#f3f3f3">
<td>Henderson</td>
<td>Nathan</td>
<td>2/25/1949</td>
<td>1</td>
</tr>
<tr style="background-color:#B4D6FC">
<td>Williams</td>
<td>James</td>
<td>7/8/1980</td>
<td>4</td>
</tr>
<tr style="background-color:#f3f3f3">
<td>Gilliam</td>
<td>Micheal</td>
<td>7/22/1949</td>
<td>1</td>
</tr>
<tr style="background-color:#f3f3f3">
<td>Smith</td>
<td>John</td>
<td>7/12/1978</td>
<td>2</td>
</tr>
<tr style="background-color:#B4D6FC">
<td>Johnson</td>
<td>Betty</td>
<td>10/15/1977</td>
<td>4</td>
</tr>
<tr style="background-color:#f3f3f3">
<td>Henderson</td>
<td>Nathan</td>
<td>2/25/1949</td>
<td>1</td>
</tr>
<tr style="background-color:#B4D6FC">
<td>Williams</td>
<td>James</td>
<td>7/8/1980</td>
<td>4</td>
</tr>
<tr style="background-color:#f3f3f3">
<td>Gilliam</td>
<td>Micheal</td>
<td>7/22/1949</td>
<td>1</td>
</tr>
</tbody>
</table>
<span id="s"></span>
<table>
<tr>
<td><a href="#" onclick="page.firstPage();">首页</a></td>
<td><a href="#" onclick="page.prePage();">上一页</a></td>
<td>第<span id="pageindex">1</span>页</td>
<td><a href="#" onclick="page.nextPage();">下一页</a></td>
<td><a href="#" onclick="page.lastPage();">尾页</a></td>
<td>第<select id="pageselect" onchange="page.changePage();"></select>页</td>
</tr>
</table>
</body>
</html>
后来实现了效果之后,发现数据量过多(10000+条)后用前台拼table这种方式会导致网页加载变得异常慢,所以就用后台分页的方法重做了一次分页功能
首先需要建一个page类,存放分页的信息
public class Pager {
private int pageIndex;//第几页
private int pageSize;//一页显示多少行
private int totalRecord;//总共多少条记录
private int totalPage;//总共多少页
private List datas;//存放数据
public int getPageIndex() {
return pageIndex;
}
public void setPageIndex(int pageIndex) {
this.pageIndex = pageIndex;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalRecord() {
return totalRecord;
}
public void setTotalRecord(int totalRecord) {
this.totalRecord = totalRecord;
}
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public List getDatas() {
return datas;
}
public void setDatas(List datas) {
this.datas = datas;
}
}
查询的时候将分页信息传入sql中:
int start = (pageIndex-1)*pageSize;
String sql = "select * from (SQL语言) a where rownum<=start+pageSize) where num>start
这样就查询出了分页的信息
在前台展示分页即可,前台需要定义一个int pageSize = 20;//每页显示多上行数据
int pageIndex = 1;//页数
这里只记录前台分页的代码块
<%if(pager!=null){%>
<table>
<tr>
<td>
<%
String url = "CMCCBoardBandHisQuery?OprType=CMCCBoardBandHisQuery";
url += "&accept_start_date="+accept_start_date+" 00:00:00";
url += "&accept_end_date="+ accept_end_date +" 23:59:59";
url += "&station_kind=" + station_kind;
url += "&pageSize=" + pageSize;
url += "&pageIndex=";
%>
第<%= pageIndex %>页,共<%= pager.getTotalPage() %>页
<%
if (pageIndex > 1){
%>
<a href="<%=url+1 %>">首页</a>
<a href="<%=url+(pageIndex-1) %>">上一页</a>
<%
}else {
%>
首页 上一页
<%}%>
<%
if (pageIndex < pager.getTotalPage()){
%>
<a href="<%=url+(pageIndex+1) %>">下一页</a>
<a href="<%=url+pager.getTotalPage() %>">尾页</a>
<%
}else {
%>
下一页 尾页
<%}%>
跳转至第
<label>
<select id="page" name="page" onchange="redirect();">
<%
for ( int i = 1; i <= pager.getTotalPage(); i++){
if (i == pageIndex){
%>
<!--当前页页码默认选中-->
<option selected value="<%= i%>"><%= i %></option>
<%
}else {
%>
<option value="<%= i %>"><%= i %></option>
<%
}
}%>
</select>
</label> 页
</td>
</tr>
</table>
<%} %>
这样就完成了分页效果,优点是前台一次性不用加载过多的table,网页加载速度变快,缺点是每次点上一页,下一页等都会完成一次与数据库的交互,大家依情况自己选择吧。
相关文章推荐
- javascript入门
- html写个超连接通过jstl传参问题
- JSON.parse()和JSON.stringify()
- JSP页面展示多个PDF文件
- 用js onselectstart事件鼠标禁止选中文字
- javascript笔记—— Math.sin() 与 Math.cos() 用法 来自博客园 岁月星空
- JavaScript 踩坑心得— 为了高速(下)
- JavaScript 踩坑心得— 为了高速(下)
- switf 字符串转 json数据 ,json数据再转化为数组
- JavaScript-----获取本月第一天、最后一天的日期
- IE6-能让png图片有透明效果的js代码
- JSP有三种注释方式
- js页面reload问题
- GridView 服务端控件添加 js
- 用script实现内容显示,并使用json传输数据
- TouchPoint.js – 可视化展示 HTML 原型点击效果
- jsp有哪些内置对象?作用分别是什么? 分别有什么方法?
- JavaScript 踩坑心得— 为了高速(上)
- JavaScript 踩坑心得— 为了高速(上)
- ArcGIS API for JavaScript开发教程系列(一)之创建地图