仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 563|回复: 10
打印 上一主题 下一主题

[学习教程] JAVA编程:今朝最好的JSP分页手艺(思索到数据库移...

[复制链接]
愤怒的大鸟 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:10:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
java比较简单,没有C++的烦琐,但学习时最好有C++为基础.与JSP和SQL起应用,功能强大.js|分页|数据|数据库  媒介
  在利用数据库的过程当中,不成制止的必要利用到分页的功效,但是JDBC的标准对此却没有很好的办理。关于这个需求良多伴侣都有本人的办理计划,好比利用Vector等汇合类先保留掏出的数据再分页。但这类办法的可用性很差,与JDBC自己的接口完整分歧,对分歧范例的字段的撑持也欠好。这里供应了一种与JDBC兼容性十分好的计划。
  JDBC和分页
  Sun的JDBC标准的制订,偶然很让人啼笑皆非,在JDBC1.0中,关于一个了局集(ResultSet)你乃至只能实行next()操纵,而没法让其向后转动,这就间接招致在只实行一次SQL查询的情形下没法取得了局集的巨细。以是,假如你利用的是JDBC1.0的驱动,那末是几近没法完成分页的。
  幸亏Sun的JDBC2标准中很好的填补了这一个不敷,增添了却果集的前后转动操纵,固然仍旧不克不及间接撑持分页,但我们已能够在这个基本上写出本人的可撑持分页的ResultSet了。
  和详细数据库相干的完成办法
  有一些数据库,如Mysql,Oracle等有本人的分页办法,好比Mysql可使用limit子句,Oracle可使用ROWNUM来限定了局集的巨细和肇端地位。这里以Mysql为例,其典范代码以下:
//盘算总的纪录条数
StringSQL="SELECTCount(*)AStotal"+this.QueryPart;
rs=db.executeQuery(SQL);
if(rs.next())
Total=rs.getInt(1);
//设置以后页数和总页数
TPages=(int)Math.ceil((double)this.Total/this.MaxLine);
CPages=(int)Math.floor((double)Offset/this.MaxLine+1);
//依据前提判别,掏出所需纪录
if(Total>0){
SQL=Query+"LIMIT"+Offset+","+MaxLine;
rs=db.executeQuery(SQL);
}
returnrs;
}
  毫无疑问,这段代码在数据库是Mysql时将会是大度的,可是作为一个通用的类(现实上我前面要供应的就是一个通用类库中的一部分),必要顺应分歧的数据库,而基于这个类(库)的使用,也大概利用分歧的数据库,以是,我们将不利用这类办法。
  另外一种烦琐的完成办法
  我看过一些人的做法(现实上包含我在内,一入手下手也是利用这类办法的),即不利用任何封装,在必要分页的中央,间接操纵ResultSet滚到响应的地位,再读取响应数目的纪录。其典范代码以下:
<%
sqlStmt=sqlCon.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,
java.sql.ResultSet.CONCUR_READ_ONLY);
strSQL="selectname,agefromtest";
//实行SQL语句并猎取了局集
sqlRst=sqlStmt.executeQuery(strSQL);
//猎取纪录总数
sqlRst.last();
intRowCount=sqlRst.getRow();
//记算总页数
intPageCount=(intRowCount+intPageSize-1)/intPageSize;
//调剂待显现的页码
if(intPage>intPageCount)intPage=intPageCount;
%>
<tableborder="1"cellspacing="0"cellpadding="0">
<tr>
<th>姓名</th>
<th>岁数</th>
</tr>
<%
if(intPageCount>0){
//将纪录指针定位到待显现页的第一笔记录上
sqlRst.absolute((intPage-1)*intPageSize+1);
//显现数据
i=0;
while(i<intPageSize&&!sqlRst.isAfterLast()){
%>
<tr>
<td><%=sqlRst.getString(1)%></td>
<td><%=sqlRst.getString(2)%></td>
</tr>
<%
sqlRst.next();
i++;
}
}
%>
</table>
  很明显,这类办法没有思索到代码重用的成绩,不但代码数目伟大,并且在代码必要修正的情形下,将会莫衷一是。
  利用Vector举行分页
  还见过另外一些完成分页的类,是先将一切纪录都select出来,然后将ResultSet中的数据都get出来,存进Vector等汇合类中,再依据所需分页的巨细,页数,定位到响应的地位,读取数据。大概先利用后面提到的两种分页办法,获得所需的页面以后,再存进Vector中。
  扔开代码的效力不说,单是从程序布局和利用的便利性上讲,就是很糟的。好比,这类做法撑持的字段范例无限,int,double,String范例还对照优点理,假如碰着Blob,Text等范例,完成起来就很贫苦了。这是一种更不成取的计划。
  一个新的Pageable接口及实在现
  很明显,看过下面三种完成办法后,我们对新的分页机制有了一个方针,即:不与详细数据库相干;尽量做到代码重用;尽量与原JDBC接口的利用办法坚持分歧;尽量高的效力。
  起首,我们必要供应一个与java.sql.ResultSet向下兼容的接口,把它定名为Pageable,接口界说以下:
publicinterfacePageableextendsjava.sql.ResultSet{
/**前往总页数
*/
intgetPageCount();
/**前往以后页的纪录条数
*/
intgetPageRowsCount();
/**前往分页巨细
*/
intgetPageSize();
/**转到指定页
*/
voidgotoPage(intpage);
/**设置分页巨细
*/
voidsetPageSize(intpageSize);
/**前往总纪录行数
*/
intgetRowsCount();
/**
*转到以后页的第一笔记录
*@exceptionjava.sql.SQLException非常申明。
*/
voidpageFirst()throwsjava.sql.SQLException;
/**
*转到以后页的最初一笔记录
*@exceptionjava.sql.SQLException非常申明。
*/
voidpageLast()throwsjava.sql.SQLException;
/**前往以后页号
*/
intgetCurPage();
}
  这是一个对java.sql.ResultSet举行了扩大的接口,次要是增添了对分页的撑持,如设置分页巨细,跳转到某一页,前往总页数等等。
  接着,我们必要完成这个接口,因为这个接口承继自ResultSet,而且它的年夜部分功效也都和ResultSet原有功效不异,以是这里利用了一个复杂的Decorator形式。
  PageableResultSet2的类声明和成员声明以下:
publicclassPageableResultSet2implementsPageable{
protectedjava.sql.ResultSetrs=null;
protectedintrowsCount;
protectedintpageSize;
protectedintcurPage;
protectedStringcommand="";
}
  能够看到,在PageableResultSet2中,包括了一个ResultSet的实例(这个实例只是完成了ResultSet接口,现实上它是由各个数据库厂商分离完成的),而且把一切由ResultSet承继来的办法都间接转发给该实例来处置。
  PageableResultSet2中承继自ResultSet的次要办法:
//……
publicbooleannext()throwsSQLException{
returnrs.next();
}
//……
publicStringgetString(StringcolumnName)throwsSQLException{
try{
returnrs.getString(columnName);
}
catch(SQLExceptione){//这里是为了增添一些堕落信息的内容便于调试
thrownewSQLException(e.toString()+"columnName="
+columnName+"SQL="+this.getCommand());
}
}
//……
  只要在Pageable接口中新增的办法才必要本人的写办法处置。
/**办法正文可参考Pageable.java
*/
publicintgetCurPage(){
returncurPage;
}
publicintgetPageCount(){
if(rowsCount==0)return0;
if(pageSize==0)return1;
//calculatePageCount
doubletmpD=(double)rowsCount/pageSize;
inttmpI=(int)tmpD;
if(tmpD>tmpI)tmpI++;
returntmpI;
}
publicintgetPageRowsCount(){
if(pageSize==0)returnrowsCount;
if(getRowsCount()==0)return0;
if(curPage!=getPageCount())returnpageSize;
returnrowsCount-(getPageCount()-1)*pageSize;
}
publicintgetPageSize(){
returnpageSize;
}
publicintgetRowsCount(){
returnrowsCount;
}
publicvoidgotoPage(intpage){
if(rs==null)
return;
if(page<1)
page=1;
if(page>getPageCount())
page=getPageCount();
introw=(page-1)*pageSize+1;
try{
rs.absolute(row);
curPage=page;
}
catch(java.sql.SQLExceptione){
}
}
publicvoidpageFirst()throwsjava.sql.SQLException{
introw=(curPage-1)*pageSize+1;
rs.absolute(row);
}
publicvoidpageLast()throwsjava.sql.SQLException{
introw=(curPage-1)*pageSize+getPageRowsCount();
rs.absolute(row);
}
publicvoidsetPageSize(intpageSize){
if(pageSize>=0){
this.pageSize=pageSize;
curPage=1;
}
}
  //PageableResultSet2的机关办法:
publicPageableResultSet2(java.sql.ResultSetrs)throwsjava.sql.SQLException{
if(rs==null)thrownewSQLException("givenResultSetisNULL","user");
rs.last();
rowsCount=rs.getRow();
rs.beforeFirst();
this.rs=rs;
}
/*假如要进步效力,能够使用selectcount(*)语句获得一切纪录数,正文失落机关函数的rs.last();rowsCount=rs.getRow();rs.beforeFirst();三句。在挪用机关函数后挪用此办法取得一切的纪录,参数是selectcount(*)后的了局集
*/
publicvoidsetRowsCount(java.sql.ResultSetrs)throwsjava.sql.SQLException{
if(rs==null)thrownewSQLException("givenResultSetisNULL","user");
rowCount=rs.getInt(1);
}
  这里只是复杂的获得一个总纪录数,并将纪录游标移回初始地位(beforefirst),同时将参数中的ResultSet赋给成员变量。
  这里只是复杂的获得一个总纪录数,并将纪录游标移回初始地位(beforefirst),同时将参数中的ResultSet赋给成员变量。
  Pageable的利用办法
  由于Pageable接口承继自ResultSet,以是在利用办法上与ResultSet分歧,特别是在不必要分页功效的时分,能够间接当做ResultSet利用。而在必要分页时,只必要复杂的setPageSize,gotoPage,便可。
PreparedStatementpstmt=null;
Pageablers=null;
……//机关SQL,并筹办一个pstmt.
rs=newPageableResultSet2(pstmt.executeQuery());//机关一个Pageable
rs.setPageSize(20);//每页20个纪录
rs.gotoPage(2);//跳转到第2页
for(inti=0;i<rs.getPageRowsCount();i++){//轮回处置
intid=rs.getInt(“ID”);
……//持续处置
rs.next();
}
  总结
  一个好的基本类应当是便于利用,而且具有充足的可移植性,同时要包管其功效的完美。在下面的完成中,我们从java.sql.ResultSet接口承继出Pageable,并完成了它。这就包管了在利用中与JDBC原有操纵的分歧性,同时对原有功效没有缩减。
  同时它也是易于利用的,由于封装了统统需要的操纵,以是在你的代码中独一显得"丢脸"和"不恬逸"的中央就是必要本人往机关一个PageableResultSet2。不外只需你乐意,这也是能够办理的。
  固然它也有具有充实的可移植性,当你将数据库由Oracle变成Mysql大概SQLServer的时分,你仍旧可使用这些分页的代码。它在利用中(大概说在移植的过程当中)独一的限定就是你必需要利用一个撑持JDBC2的驱动(如今分明为何我把类定名为PageableResultSet2了吧。:P),不外,幸亏JDBC2已成为尺度了,尽年夜多半的数据库(如Oracle,Mysql,SQLServer)都有本人的大概第三方供应的JDBC2的驱动。
  OK,这个分页的完成是不是对你的编程有匡助呢?细心看看,实在真正本人写的代码其实不多的,年夜部分都只是复杂的转发操纵。一个符合的形式使用能够帮你很年夜忙。

专门做了这个例子;而java的这个例子好像就是为了教学而写的,很多教学目的的例子是不考虑优化、性能的。
灵魂腐蚀 该用户已被删除
沙发
发表于 2015-1-20 15:48:30 | 只看该作者
任职于太阳微系统的詹姆斯·高斯林等人于1990年代初开发Java语言的雏形,最初被命名为Oak,目标设置在家用电器等小型系统的程序语言
愤怒的大鸟 该用户已被删除
板凳
 楼主| 发表于 2015-1-23 06:01:32 | 只看该作者
Java自面世后就非常流行,发展迅速,对C++语言形成了有力冲击。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于个人PC、数据中心、游戏控制台
飘飘悠悠 该用户已被删除
地板
发表于 2015-1-31 14:58:28 | 只看该作者
设计模式是高级程序员真正掌握面向对象核心思想的必修课。设计模式并不是一种具体"技术",它讲述的是思想,它不仅仅展示了接口或抽象类在实际案例中的灵活应用和智慧
不帅 该用户已被删除
5#
发表于 2015-2-6 19:46:00 | 只看该作者
在全球云计算和移动互联网的产业环境下,Java更具备了显著优势和广阔前景。
爱飞 该用户已被删除
6#
发表于 2015-2-7 04:54:12 | 只看该作者
如果你学过HTML,那么事情要好办的多,如果没有,那你快去补一补HTML基础吧。其实JSP中的Java语法也不多,它更象一个脚本语言,有点象ASP。
深爱那片海 该用户已被删除
7#
发表于 2015-2-8 08:50:09 | 只看该作者
[url]http://www.jdon.com/[/url]去下载,或到同济技术论坛的服务器[url]ftp://nro.shtdu.edu.cn[/url]去下,安装上有什么问题,可以到论坛上去提问。
因胸联盟 该用户已被删除
8#
发表于 2015-2-25 05:56:11 | 只看该作者
Java 不同于一般的编译执行计算机语言和解释执行计算机语言。它首先将源代码编译成二进制字节码(bytecode),然后依赖各种不同平台上的虚拟机来解释执行字节码。从而实现了“一次编译、到处执行”的跨平台特性。
若天明 该用户已被删除
9#
发表于 2015-3-7 17:10:14 | 只看该作者
有时间再研究一下MVC结构(把Model-View-Control分离开的设计思想)
莫相离 该用户已被删除
10#
发表于 2015-3-15 09:56:43 | 只看该作者
一直感觉JAVA很大,很杂,找不到学习方向,前两天在网上找到了这篇文章,感觉不错,给没有方向的我指了一个方向,先不管对不对,做下来再说。
兰色精灵 该用户已被删除
11#
发表于 2015-3-22 00:10:09 | 只看该作者
是一种简化的C++语言 是一种安全的语言,具有阻绝计算机病毒传输的功能
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-11-14 22:30

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表