关于EXT-JS分页问题请教

aptweasel 2013-01-27 04:01:44
最近初学EXT-JS,对它还不是很了解,网上没有找到好的解决办法,所以请教一下大家
我希望是一次性把所需要的数据全部查出来,写成一个JSMON数组,下放到页面, 这样在WEB页面上刷新时都是前台处理,以减少后台的请求压力。

但是实际情况是我发现,前台每次都把所有的数据全都加载到页面了
即,我设置每页10条,如果总共有59条记录,它会产生6页数据,每页都是59条。

然后我通过前台发到后台的参数,让页面每次只取中页面上应该取的数据,这样显示效果就对了,但是后台压力非常大。
即我每刷新一页,或翻页,它都会去后台请求,而且请求的次数是页面条数的两倍,即每次翻一页都要请求数据库20次,而且每次数据库请求都是取这所有的59条记录,到了前端根据分页信息再截取对应信息。

这样的话,分页不仅没有达到减轻服务器压力的初衷,反而成倍提高了服务器的压力,得不偿失。

我下面把源代码贴出来,请帮我看看应该如何修正,谢谢
数据库表结构
CREATE TABLE MON_SERVER_CONFIG
(
INDEX_NO NUMBER(8) NOT NULL,
NAME VARCHAR2(20 CHAR) NOT NULL,
VALUE VARCHAR2(40 CHAR) NOT NULL,
COMMON VARCHAR2(200 CHAR),
IS_CONFIG VARCHAR2(2 CHAR) NOT NULL
);
用于页面展示的页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<HTML>
<HEAD>
<TITLE>SmartMonitor</TITLE>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css"
href="../ext-4.0/resources/css/ext-all.css" />
<script type="text/javascript" src="../ext-4.0/bootstrap.js">
</script>
<script type="text/javascript"
src="../ext-4.0/locale/ext-lang-zh_CN.js">
</script>
<script type="text/javascript">
var ctxpath = '<%=basePath%>';

Ext.Loader.setConfig( {
enabled : true
});

Ext.Loader.setPath('Ext.ux', '../ext-4.0/ux/');

Ext.require( [ 'Ext.data.*', 'Ext.grid.*', 'Ext.util.*',
'Ext.ux.data.PagingMemoryProxy', 'Ext.ux.ProgressBarPager' ]);

Ext.onReady(function() {
var itemsPerPage = 20;//指定分页大小
var store = Ext.create('Ext.data.Store', {
autoLoad : {
start : 0,
limit : itemsPerPage
},
fields : [ 'name', 'value', 'common' ],
pageSize : itemsPerPage, //设置分页大小
proxy : {
type : 'ajax',
url : ctxpath + 'system/configList.jsp',
reader : {
type : 'json',
root : 'properties',
totalProperty : 'total'
}
}
});

//创建Grid表格组件
var grid = Ext.create('Ext.grid.Panel', {
renderTo : Ext.getBody(),
frame : true,
layout : 'fit',
ViewConfig : {
forceFit : true,
scripeRows : true
},
multiSelect : true,//支持多选
selModel : {
selType : 'checkboxmodel'//复选框选择模式Ext.selection.CheckboxModel
},
store : store,
columns : [//配置表格列
Ext.create('Ext.grid.RowNumberer', {
text : '行号',
width : 35
}), {
header : "参数名称",
width : 200,
//sortable : false,
dataIndex : 'name'
}, {
header : "参数值",
width : 100,
//sortable : false,
dataIndex : 'value'
}, {
header : "描述",
width : 300,
//sortable : false,
dataIndex : 'common'
} ],
tbar : [ {
xtype : 'buttongroup',
items : [ {
text : 'Add',
icon : '../images/add.gif',
scale : 'medium'
}, {
text : 'Edit',
icon : '../images/edit.gif',
scale : 'medium',
handler : function() {
//获取被操作的数据记录
var msg = '';
var rows = grid.getSelectionModel().getSelection();
if (rows.length == 0) {
alert('请选择一行编辑');
} else if (rows.length > 1) {
alert('只能选择一行编辑');
} else {
alert('编辑' + rows[0].get('name'));
}
}
}, {
text : 'Delete',
icon : '../images/del.gif',
scale : 'medium',
handler : function() {
var msg = '';
var rows = grid.getSelectionModel().getSelection();
if (rows.length == 0) {
alert('请至少选择一行');
} else {
for ( var i = 0; i < rows.length; i++) {
msg = msg + rows[i].get('name') + '\n';
}
alert(msg);
}
}
} ]
} ],
dockedItems : [ {
xtype : 'pagingtoolbar',
pageSize : itemsPerPage,
store : store, // same store GridPanel is using
dock : 'bottom',
emptyMsg: "没有记录",
displayInfo : true
} ]
});
});
</script>
</head>
<BODY STYLE="margin: 0px"></BODY>
</html>

用于管理页面回显数据的页system/configList.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ page import="java.util.*"%>
<%@ page import="com.dc.bus.system.PropertiesConfig"%>
<%@ page import="net.sf.json.JSONArray"%>
<%
int start=Integer.parseInt(request.getParameter("start"));
int limit=Integer.parseInt(request.getParameter("limit"));

System.out.println("start:"+start+",limit:"+limit);

PropertiesConfig pc=new PropertiesConfig();
List list=new ArrayList();
for(int i=start;i<start+limit;i++){
if(i==pc.listProperties().size()){
break;
}
list.add(pc.listProperties().get(i));
}
String str = JSONArray.fromObject(list).toString();
//System.out.println(ja.toString());

String user ="{'success': true,'total': "
+ pc.listProperties().size()+","
+ "'properties': "
+ str
+ "}";

System.out.println(user);
response.getWriter().write(user);
%>

从数据库取数据的java
/**
*
*/
package com.dc.bus.system;

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

import org.apache.log4j.Logger;

import com.dc.jdbc.LocalDB;

/**
* @author black
*
*/
public class PropertiesConfig {
private static final Logger log = Logger.getLogger(PropertiesConfig.class);

public List<HashMap> listProperties(){
List list=new ArrayList<HashMap>();
LocalDB localdb=new LocalDB();
String sql="SELECT INDEX_NO,NAME,VALUE,COMMON,IS_CONFIG FROM MON_SERVER_CONFIG where INDEX_NO<80 and INDEX_NO>20";
log.info(sql);
try {
Connection conn = localdb.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs=stmt.executeQuery(sql);
while(rs.next()){
PropertyBean bean=new PropertyBean();
bean.setIndex_no(rs.getString("INDEX_NO"));
bean.setName(rs.getString("NAME"));
bean.setValue(rs.getString("VALUE"));
bean.setCommon(rs.getString("COMMON"));
bean.setIsConfig(rs.getString("IS_CONFIG"));
list.add(bean);
}
rs.close();
stmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
}

下面是程序中用到的一个JAVABEAN
/**
*
*/
package com.dc.bus.system;

/**
* @author black
*
*/
public class PropertyBean {
private String index_no;
private String name;
private String value;
private String common;
private String isConfig;
/**
* 省略get set方法
*/
}

请各路大仙帮分析下,是什么原因,正确的方法应该是怎么样的,谢谢!

...全文
238 7 点赞 打赏 收藏 举报
写回复
7 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
aptweasel 2013-05-29
最后,把resultSetOfQury对象转成JSON报文,返回给前端,就可以了
  • 打赏
  • 举报
回复
aptweasel 2013-05-29
首先我说一下现象,不是原理 我通过测试发现,对于一次性拿到所有数据的分页,程序不会向后台请求,这样,就要把所有数据通过JAVA代码生成数组,然后做成静态分页,这种写法复杂,而且性能很差,估计也没有人愿意用。 第二种方法,就是我希望实现的,我动态去后台取数的方法,但是ORACLE不支持这种办法,那就要自己实现:我通过测试发现,每点一次翻页,它都需要向后台请求,发送报文,返回的当然也是JSON报文。这就好办了,不要把希望寄托在前端,前端按照规范做,网上上大堆这样的例子,我就不啰嗦了,关键是后台,前端每次的请求,我都按要求组织报文返回前端,就实现了翻页功能,但是这种方法也有弊端,就是增加了数据库的压力:每个查询或翻页时SQL需要在数据库中执行两次,一次统计返回总行数,一次取出所需要记录。数据量越大,压力越大,所以要尽量控制结果集的大小,增加一些静态查询条件,剔出不必要的记录。 下我我写一下我的实现方法,我做了一个通用查询,它需要上传以下几个参数:SQL语句,起始行号及返回行数,创建一个结果集对象 /*分页对象*/ public class PagePropery { int start; // 起始行号 int limit; // 获取行数 int count; // 查询条件总返回行数,下送参数 /**get set方法自己补充***/ } public class resultSetOfQury{ private int count; private List<HashMap<String,String>> result; /**get set方法自己补充***/ } /************* *返回原SQL总行数 * */ private int getPagingCount(String sql) throws SQLException { Connection conn = this.getConnection(); Statement stmt = conn.createStatement(); String sql_qury = "select count(*) cut from (" + sql + ") t"; log.info("sql_qury:" + sql_qury); ResultSet rs = stmt.executeQuery(sql_qury); int count = 0; while (rs.next()) { count = rs.getInt("cut"); } rs.close(); stmt.close(); conn.close(); return count; } 把查询的总行数,返回给count,把第start,limit传给通用查询 /************* * sql,传入需要执行的查询语句 PagePropery 页码信息 start:从第几行开始 limit:取出多少行 * count:是传出参数,返回原SQL总行数 * */ public List<HashMap<String, String>> executePagingQuery(String sql, PagePropery page) { Connection conn = this.getConnection(); Statement stmt; List<HashMap<String, String>> list = new ArrayList(); int end = page.getStart() + page.getLimit(); String sql_qury = "select * from (select t.*,rownum rowno from (" + sql + ") t) where rowno between " + page.getStart() + " and " + end; log.info("sql_qury:" + sql_qury); try { page.setCount(this.getPagingCount(sql)); stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql_qury); ResultSetMetaData md = rs.getMetaData(); int count = md.getColumnCount(); Vector<String> v = new Vector(); for (int i = 1; i <= count; i++) { String column = md.getColumnLabel(i); v.add(md.getColumnName(i).toLowerCase()); } while (rs.next()) { HashMap<String, String> hp = new HashMap(); for (String var : v) { hp.put(var, Tools.nvl(rs.getString(var))); } list.add(hp); } rs.close(); stmt.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } return list; }
  • 打赏
  • 举报
回复
ling00_00 2013-05-28
我想实现的功能与楼主类似,即在前台实现分页查询的功能,查询结果由后台以json格式推送到前台,但推送回来的数据集比较大,如果在后台实现分页会增大响应时间,也会增加后台压力。 我也是在官网上看到PagingMemoryProxy能够实现我想要的功能。但我也是初学ExtJs 4,也没找到官方提供的这方面的例子,看到楼主的帖子想必楼主已经实现了相关功能,能否提供给我一个例子学习一下呢,万分感谢! 邮箱地址xiaolingbell@126.com
  • 打赏
  • 举报
回复
aptweasel 2013-02-02
哥们,怎么没有后台代码? 其实我的代码,上面贴出来的部分,还是有问题的,但是我已经修改对了。后来想想,代码跟上面比起来,只是换了请求方法,没有本质上的区别。 我是刚刚学习EXTJS,所以不太懂,再加上它的API写的也不是很好,理解不了。 我看过你的代码,其实就页面显示部分来讲,没有本质区别,你的代码和我上面的基本没有本质区别,都是依赖于后台给你返回的数据,这样对后台服务器压力很大,每次翻页都要去后台请求一次。 其实我在是官方给的例子中看到一个对象:Ext.ux.data.PagingMemoryProxy 这个对象能实现数据在前端分页。就是说你做一次查询,后台把所有的数据都返回来,然后前端对这个数据自动分页,但是我们采用了 var store = new Ext.data.Store({ proxy: new Ext.data.HttpProxy({url: 'PageServlet'}), //后台分页 reader: new Ext.data.JsonReader({ totalProperty: 'totalProperty', root: 'data' } 就不能用Ext.ux.data.PagingMemoryProxy这个对象了。 当然这也是因为跟数据库有很大的区别: 如果用MYSQL,其实用分页基本没有问题了,因为MYSQL的SQL支持limit start_rows,limit_rows这样的写法,但是我用的是ORACLE,如果查子集,其实对数据库并不会因为你限制了行数而减轻压力,反而因为分页,会增加数据库的压力。所以我希望把这个压力推到前台去。
  • 打赏
  • 举报
回复
xiaomm627 2013-01-29
没人回帖也不奇怪,你这一上来老长老长代码一贴,贴就贴了把,您老也用编辑器里的代码格式啊,这看了不头晕啊。。。 按你所说,就是没有实现分页效果了。我贴你一个正常的,你自己比对出错在哪里:


<%@ 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">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>分页</title>
<link rel="stylesheet" type="text/css" href="ext/resources/css/ext-all.css" />
<script type="text/javascript" src="ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="ext/ext-all.js"></script>
<script type="text/javascript" src="ext/expand/RowEditor.js"></script>
<link rel="stylesheet" type="text/css" href="ext/expand/roweditorgrid.css" />
<script type="text/javascript" src="ext/ext-lang-zh_CN-utf8.js"></script>



</head>
<body>
<div id="grid"></div><br>
</body>

<script language="javascript">
Ext.onReady(function() {

var sm = new Ext.grid.CheckboxSelectionModel({handleMouseDown: Ext.emptyFn});
//建立列模型
var cm = new Ext.grid.ColumnModel([
  sm,
  {header:'编号',dataIndex:'id',sortable: true, editor: {xtype: 'numberfield'}},// sortable: true 排序1
  {header:'名称',dataIndex:'name',sortable: true, editor: {xtype: 'textfield'}},
  {header:'描述',dataIndex:'descn',sortable: true, editor: {xtype: 'textfield'}},
  {header:'状态',dataIndex:'state',sortable: true, editor: {xtype: 'checkbox'}}
  
]);


var MyRecord = Ext.data.Record.create([
   {name: 'id',type: 'int'},
   {name: 'name',type: 'string'},
   {name: 'descn',type: 'string'},
   {name: 'state',type: 'checkbox'}
]);
var addstore = new Ext.data.Store({//用于存储新增行的数据
       reader:new Ext.data.ArrayReader({},MyRecord)
   });

//转化数据
var store = new Ext.data.Store({
   proxy: new Ext.data.HttpProxy({url: 'PageServlet'}), //后台分页
   reader: new Ext.data.JsonReader({
       totalProperty: 'totalProperty',
       root: 'data'
   },[
       {name: 'id'},
       {name: 'name'},
       {name: 'descn'},
       {name: 'state'}
   ]),
   //remoteSort: true,//后台排序
   sortInfo:{field: 'id',direction: 'ASC'}//排序2
}); 


//装配
var pageSize = 10;
var grid = new Ext.grid.GridPanel({
  renderTo: 'grid',
  width: 1000,
  height: 300,
  plugins: [new Ext.ux.grid.RowEditor()],
  loadMask: true,
  autoHeight:true, 
  store: store,
  cm: cm,
  sm: sm,
  viewConfig:{
    columnsText: '要显示的列',//要显示的列
    scrollOffset: 25,//为滚动条预留的宽度
    forceFit: true
  },
  bbar: new Ext.PagingToolbar({
     pageSize: pageSize,
     store: store,
     displayInfo: true,
     displayMsg: '显示第 {0} 条到 {1} 条记录,一共 {2} 条',
     emptyMsg: '没有记录'
  })
  
});

store.load({
   params:{
      start: 0,
      limit: pageSize
   }
});




});


</script>
</html>
  • 打赏
  • 举报
回复
dalong_zh 2013-01-29
我不是高手 ,但用过ext1 2 3 没有用过4 你的问题我没怎么看懂,真的, ext grid 分页显示, 后台分页查询很麻烦么? 别喷我 呵呵
  • 打赏
  • 举报
回复
aptweasel 2013-01-27
怎么还是没有人来回帖子呢?我决定再留一周看看,就散分贴了 我把查询过程重新写了一下,分成两个函数做,一个按上送的页号和取多少行,一次性取出符合条件的数据,一个过程查询SQL执行实际有多少行数,这样呢虽然每次页面刷新还是会执行两次查询,但是比上面的代码要执行的快的多了。 不知道各路大仙有没有更好的办法呢?
  • 打赏
  • 举报
回复
相关推荐
发帖
Web 开发
加入

8.0w+

社区成员

Java Web 开发
申请成为版主
帖子事件
创建了帖子
2013-01-27 04:01
社区公告
暂无公告