用SWT中的虚拟表格解决大数据量加载问题.docx
- 文档编号:14282455
- 上传时间:2023-06-22
- 格式:DOCX
- 页数:20
- 大小:71.84KB
用SWT中的虚拟表格解决大数据量加载问题.docx
《用SWT中的虚拟表格解决大数据量加载问题.docx》由会员分享,可在线阅读,更多相关《用SWT中的虚拟表格解决大数据量加载问题.docx(20页珍藏版)》请在冰点文库上搜索。
用SWT中的虚拟表格解决大数据量加载问题
心之所向,所向披靡
用SWT中的虚拟表格解决大数据量加载问题
此文引用网站以为兄弟的,具体地址记得不是很清楚。
但是主体内容一样。
问题的提出:
一般情况下,我们采用分页技术来解决大数据量加载的问题,这也是最好的办法。
但是在有的项目中会遇到一次加载"万单位级别"数据的需求。
尽管这是很糟糕的做法,即耗资源、加载速度又慢,但用户明指明了这样的需求,不这么做还不行。
解决方法:
采用SWT中的虚拟表格技术来创建拥有大数据量的表格,解决加载速度让人难以忍受的问题,提升加载效率。
为了充分的说明问题,本文通过对比常规方法和虚拟表格技术加载2万条数据所需的时间,来说明虚拟表格在加载大数据量时的优越表现。
第一步:
准备数据
1. 首先建立所需的数据表
createtableuser(idint(10)primarykeyauto_increment,name1varchar(20),name2varchar(20),name3varchar(20),name4varchar(20))type=innodb;
2.插入数据(写测试的目的一般带有破坏性,我插了2万条)
for(inti=0;i<20000;i++)
{
Strings="chengang";
sm.executeUpdate("insertintotest_table(name0,name1,name2,name3)values('"+s+1+i+"','"+s+2+i+"','"+s+3+i+"','"+s+4+i+"')");
}
3.创建一个DAO文件,用来处理插入和获得数据:
ConnDAO.java,详细内容请参看源文件
//按照给定的sql进行数据库查询
//取出数据后,赋值个Vector,并返回
publicVectorexecuteQuery(Stringsql)
{
ResultSetrs=null;
VectorvResult=newVector();
try
{
Class.forName(driver);
con=DriverManager.getConnection(dburl,userName,password);
stmt=con.createStatement();
rs=stmt.executeQuery(sql);
ResultSetMetaDatarsmd=rs.getMetaData();
intnumCols=rsmd.getColumnCount();
while(rs.next())
{
StringstrTempArray[]=newString[numCols];
for(inti=1;i<=numCols;i++)
{
/*将存储过程得到的每个字段赋值到字符串数组,并将其做为对象加入到vector类中返回*/
strTempArray[i-1]=rs.getString(i);
}
vResult.addElement(strTempArray);
}
}catch(Exceptione)
{
System.out.println("QueryError!
!
!
!
!
!
!
!
!
");
}
returnvResult;
}
}
第二步:
创建测试文件
在开始之前,请你确认正确安装了SWTDesigner,创建一个基于SWT/JFS的项目(不是必须,但这样可以方便使用可视化编辑,当然你也可以直接编写代码)。
1.为了与虚拟表格进行对比,我们首先用普通Table加载这2万条数据。
HelloWorld_Common.java
packageedu.bjtu.zhao.demo;
//import引入相关的类,具体可以参考本文的源文件
publicclassHelloWorld_Common{
privatestaticTabletable;
/**
*Launchtheapplication
*@paramargs
*/
publicstaticvoidmain(String[]args){
//为了清晰说明问题,在此省略了相关部分代码,可以参考源代码
table=newTable(shell,SWT.BORDER);//注意此处与虚拟表格设置的不同
table.setBounds(40,30,723,290);
//此处省略了创建5列的代码,
try
{
//获得数据表格数据
ConnDAOdao=newConnDAO();
Stringss="select*fromtest_table";//SendTable为表名
finalVectorvResult=dao.executeQuery(ss);
for(inti=0;i { //因为条目都是直接创建的,这样初始化的过程就相当慢 TableItemitem=newTableItem(table,SWT.NONE); item.setText((String[])vResult.get(i)); } }catch(Exceptionexception) { exception.printStackTrace(); } } } 写完程序后,你可以直接在Eclipse中运行,运行结果如下图所示,当然不要忘记适当的计算一下时间,我的电脑的配置是: Intel双核1.73GHz,512M内存, 用的是: jdk1.5.0_06MySQLversion: 4.0.14-nt 我的运行时间约是: 10秒。 我想这样的速度,你的客户是不能忍受的,而且创建了那么多的Item,如果用户不看,且不是造成了严重的资源浪费。 2.做了这么多准备工作,下面开始令人兴奋的虚拟表格之旅吧。 创建HelloWorld_Virtual.java packageedu.bjtu.zhao.demo; //import……具体的包,可以参见附件中的源代码 publicclassHelloWorld_Virtual{ privatestaticTabletable; /** *Launchtheapplication *@paramargs */ publicstaticvoidmain(String[]args){ //finalVectorvResult=newVector(); finalDisplaydisplay=Display.getDefault(); finalShellshell=newShell();//shell是主程序窗口 shell.setSize(808,375);//设置窗体初始化大小 shell.setText("SWTApplication");//设置窗体名称 shell.open();//主程序打开 /////////////////////////创建表格////////////////////////////////// table=newTable(shell,SWT.BORDER|SWT.VIRTUAL);//注意此处的设置 table.setLinesVisible(true); table.setHeaderVisible(true); table.setBounds(40,30,723,290); ///////////////////创建表格四列//////////////////////////////////////////// finalTableColumnnewColumnTableColumn=newTableColumn(table,SWT.NONE); newColumnTableColumn.setWidth(100); newColumnTableColumn.setText("id"); ///同样的方法创建另外4列 //////////////////////////////////////////////////////////////////////////////////////////////////// //获得数据表格数据 ConnDAOdao=newConnDAO(); Stringss="select*fromtest_table";//SendTable为表名 finalVectorvResult=dao.executeQuery(ss); /////////////设置监听///////////////////////////////// /*table.addListener(SWT.SetData,newListener(){ publicvoidhandleEvent(Eventevent){ TableItemitem=(TableItem)event.item; intindex=event.index; item.setText((String[])vResult.get(index)); } });*/ //////////////另一种方式实现虚拟表格/////////////////////////////////// finalintPAGE_SIZE=100; table.addListener(SWT.SetData,newListener(){ publicvoidhandleEvent(Eventevent){ TableItemitem=(TableItem)event.item; intindex=event.index; intpage=index/PAGE_SIZE; intstart=page*PAGE_SIZE; intend=start+PAGE_SIZE; end=Math.min(end,table.getItemCount()); for(inti=start;i item=table.getItem(i); item.setText((String[])vResult.get(i)); } } }); //////////////设计总记录数,便于滚动条计算////////////////////////////////////////////////// table.setItemCount(vResult.size()); shell.layout();//主程序布置 while(! shell.isDisposed()){//如果主程序没有关闭,这一直循环 if(! display.readAndDispatch())//如果不忙 display.sleep();//休眠 } } } 呵呵,run一下吧,我测试的结果,算上绘制界面的时间也就1秒左右,如果在界面上做个查询,再来显示的话,基本“万单位”级别的数据也能做到即时加载啦 在源代码中我已经做了较详细的注释,因为本文主要以实际操作为主,所以没有对具体的方法进行深入的分析。 另外一个原因就是,现在网上有一篇文章《VirtualTablesandTrees》对虚拟表格和树做了较深入的分析,我不再重复他人的劳动,你可以参考一下。 网上有这篇文章的中文版,不过如果你打算在IT界混的话,还是建议你读英文吧 publicclassTableViewerContentProviderimplementsIStructuredContentProvider{ publicObject[]getElements(Objectelement){ if(elementinstanceofList){ return((List)element).toArray(); }else{ returnnewObject[0]; } } publicvoiddispose(){ //TODO自动生成方法存根 } publicvoidinputChanged(Viewerviewer,ObjectoldInput,ObjectnewInput){ //TODO自动生成方法存根 } } //ListinputObj=VisitInformationFactory.getInformations(); //tableViewer.setInput(inputObj); 这两行的意思是得到数据库表中的所有的数据,并加入到tableViewer中 给SWT表格添加虚拟表显示数据库检索得到的结果(使用Java集合实现)2009-01-0923: 14/** * (1)单击检索按钮之后,将检索的结果保存在一个集合对象中; * (2)根据当前要显示的数据的页码,采用虚拟表或直接给表格项目赋值的方法显示相应的数据 *(3)计算检索结果在表格中可显示的总页数 */ packagecgmpc.database; importjava.sql.ResultSet; importjava.sql.ResultSetMetaData; importjava.util.ArrayList; importorg.eclipse.swt.SWT; importorg.eclipse.swt.widgets.Event; importorg.eclipse.swt.widgets.Listener; importorg.eclipse.swt.widgets.Table; importorg.eclipse.swt.widgets.TableItem; importcgmpc.database.OperateDatabase; publicclassCurrentTableDispaly{ privateintpagesize=0;//表格的每页所显示的记录条数 //保存检索结果的集合类对象 privateArrayList privateintrecordtotalnum=0;//检索结果的总数 privateListenerdatalistener; /** *构造方法 * *@parampagecontain *表格的每页显示的记录条数 */ publicCurrentTableDispaly(intpagecontain){ pagesize=pagecontain; } /** *根据SQL语句在数据库中查询数据,并将获取的数据赋值个ArrayList * *@paramselectsqlstr *检索记录的SQL查询语句 *@returnResultSet检索结果的集合对象 */ publicArrayList ResultSetrs=null; try{ OperateDatabaseoperatedb=newOperateDatabase(); rs=operatedb.executeQuery(selectsqlstr); //可用于获取关于ResultSet ResultSetMetaDatarsmd=rs.getMetaData(); //对象中列的类型和属性信息的对象 intnumCols=rsmd.getColumnCount();//返回此ResultSet对象中的列数 while(rs.next()){ Stringstrtemparray[]=newString[numCols]; for(inti=1;i<=numCols;i++){ //将存储过程得到的每个字段赋值到字符串数组,并将其做为对象加入到vector类中返回 strtemparray[i-1]=rs.getString(i); } //向集合中增加一个新的元素 searchresultset.add(strtemparray); } recordtotalnum=searchresultset.size(); }catch(Exceptione){ e.printStackTrace(); } returnsearchresultset; } /** *建立查询结果的虚拟表,以控制记录的分页显示与快速加载即根据当前记录的页码,将数据显示在实际的Table控件上 * *@paramfacttable *显示检索结果的GUI表格对象 *@parampagenum *显示在表格对象中的检索结果页码,从1开始计算 */ publicvoidopenVirtualTable(finalTablefacttable,finalintpagenum){ //移除上次显示数据的SWT.SetData监听器 if(datalistener! =null){ facttable.removeListener(SWT.SetData,datalistener); } //清空表所有项目中的数据 facttable.clearAll(); //数据记录在检索结果结合中的下标开始值 finalintrecordstart=(pagenum-1)*pagesize; //当前表格能显示的最后一条记录在检索结果集合中的索引号 intend=recordstart+pagesize; //若表格可显示的记录大于检索结果记录的总数,就只显示到最后一条检索结果记录 finalintrecordend=Math.min(end,recordtotalnum);//显示的最后一条记录在检索结果集合中的索引号 System.out.println("检索结果的总记录数"+recordtotalnum); System.out.println("表格每页可显示的记录数"+facttable.getItemCount()); //当前页面显示的检索结果记录数 finalintcurrentdispnum=recordend-recordstart; //定义无类型事件,用于每当访问表的item域时,循环执行对项目设置数据(在表中显示数据)操作 datalistener=newListener(){ publicvoidhandleEvent(Eventevent){ TableItemitem=(TableItem)event.item; //获取项目的索引,用于计算它所在页的开始和结束项目的索引 intindex=event.index; System.out.println("当前TableItem项目索引: "+index); //在表上显示该页数据(设置该页的所有项目的数据),以后不再为这些项目调用SWT.SetData监听器 if(index System.out.println("项目索引="+index); //当前项目索引对应的TableItem项目 item=facttable.getItem(index); //设置当前TableItem项目对应检索结果集合中的数据 item.setText(searchresultset.get(recordstart+index)); }else{ //当前页的项目有空项目时,将这些项目的值初始化为空字符串,否则重新检索的时候会出现问题 item=facttable.getItem(index); //设置当前页的空TableItem项目为空字符串 String[]nullitemvalue={"","","","","",""}; item.setText(nullitemvalue); } } }; //向表添加SWT.SetData监听器 facttable.addListener(SWT.SetData,datalistener); } /** *通过将检索结果结合中的记录分页加载的方法,实现控制检索结果记录的分页显示与快速加载 * *@paramfacttable *显示检索结果的GUI表格对象 *@parampagenum *显示在表格对象中的检索结果页码,从1开始计算 */ publicvoidopenCurrentTable(finalTablefacttable,finalintpagenum){ //清空表格所有项目中的数据 facttable.clearAll(); //数据记录在检索结果结合中的下标开始值 finalintrecordstart=(pagenum-1)*pagesize; //当前表格能显示的最后一条记录在检索结果集合中的索引号 intend=recordstart+pagesize; //若表格可显示的记录大于检索结果记录的总数,就只显示到最后一条检索结果记录 finalintrecordend=Math.min(end,recordtotalnum);//显示的最后一条记录在检索结果集合中的索引号 //当前页面显示的检索结果记录数 finalintcurrentdispnum=recordend-recordstart; //根据当前的页码,从检索结果集合中加载相应的数据到表的item域中 for(inti=
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- SWT 中的 虚拟 表格 解决 数据量 加载 问题