如何测定JDBC的性能
2008-01-05 19:06:14 来源:WEB开发网 闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閻愵剙鍔ょ紓宥咃躬瀵鎮㈤崗灏栨嫽闁诲酣娼ф竟濠偽i鍓х<闁诡垎鍐f寖闂佺娅曢幑鍥灳閺冨牆绀冩い蹇庣娴滈箖鏌ㄥ┑鍡欏嚬缂併劎绮妵鍕箳鐎n亞浠鹃梺闈涙搐鐎氫即鐛崶顒夋晬婵絾瀵ч幑鍥蓟閻斿摜鐟归柛顭戝枛椤牆顪冮妶搴′簼缂侇喗鎸搁悾鐑藉础閻愬秵妫冮崺鈧い鎺戝瀹撲礁鈹戦悩鎻掝伀缁惧彞绮欓弻娑氫沪閹规劕顥濋梺閫炲苯澧伴柟铏崌閿濈偛鈹戠€n€晠鏌嶆潪鎷屽厡闁汇倕鎳愮槐鎾存媴閸撴彃鍓卞銈嗗灦閻熲晛鐣烽妷褉鍋撻敐搴℃灍闁绘挻娲橀妵鍕箛闂堟稐绨肩紓浣藉煐濮樸劎妲愰幘璇茬闁冲搫鍊婚ˇ鏉库攽椤旂》宸ユい顓炲槻閻g兘骞掗幋鏃€鐎婚梺瑙勬儗閸樺€熲叺婵犵數濮烽弫鍛婃叏椤撱垹纾婚柟鍓х帛閳锋垶銇勯幒鍡椾壕缂備礁顦遍弫濠氱嵁閸℃稒鍊烽柛婵嗗椤旀劕鈹戦悜鍥╃У闁告挻鐟︽穱濠囨嚃閳哄啰锛滈梺褰掑亰閸欏骸鈻撳⿰鍫熺厸閻忕偟纭堕崑鎾诲箛娴e憡鍊梺纭呭亹鐞涖儵鍩€椤掑啫鐨洪柡浣圭墪閳规垿鎮欓弶鎴犱桓闂佸湱枪閹芥粎鍒掗弮鍫熷仺缂佸顕抽敃鍌涚厱闁哄洢鍔岄悘鐘绘煕閹般劌浜惧┑锛勫亼閸婃牠宕濋敃鈧…鍧楀焵椤掍胶绠剧€光偓婵犱線鍋楀┑顔硷龚濞咃絿妲愰幒鎳崇喓鎷犻懠鑸垫毐闂傚倷鑳舵灙婵炲鍏樺顐ゆ嫚瀹割喖娈ㄦ繝鐢靛У绾板秹寮查幓鎺濈唵閻犺櫣灏ㄥ銉р偓瑙勬尭濡繂顫忛搹鍦<婵☆垰鎼~宥囩磽娴i鍔嶉柟绋垮暱閻g兘骞嬮敃鈧粻濠氭偣閸パ冪骇鐎规挸绉撮—鍐Χ閸℃ê闉嶇紓浣割儐閸ㄥ墎绮嬪澶嬪€锋い鎺嶇瀵灝鈹戦埥鍡楃仯闁告鍕洸濡わ絽鍟崐鍨叏濡厧浜鹃悗姘炬嫹

java数据库连接(JDBC)被广泛用在Java应用程序中。在本篇文章中,我们将讨论如何测定JDBC的性能,如何判定JDBC子系统中的哪一部分需要进行优化。
核心的java.sql界面
我们的目的是提高应用程序的性能。一般情况下,我们需要对应用程序进行分析,找出其中的瓶颈。当然了,要对分布式应用程序进行有效的分析是比较困难的,I/O是分析的一个重点,这是由分布式应用程序的特点决定的,分布式应用程序中的线程需要花费大量的时间等待I/O操作。目前还不清楚线程因等待读、写操作而阻塞是瓶颈的一部分呢还是一个无关紧要的小问题。在进行分析时,有一个独立的通信系统测试标准是重要的。那么在测试JDBC子系统的性能时,我们应当测试哪些指标呢?
在java.sql软件包中,有三个接口组成了JDBC的核心:Connection、Statement和ResultSet。与数据库的正常交互包括下面的几部分:
·从数据库驱动程序中获得一个Connection对象。
·从Connection对象中获取能够执行指定的SQL语句的Statement对象
·假如SQL语句需要从数据库中读取数据,则使用Statement对象获取一个提供对数据库中的数据进行访问的ResultSet对象。
下面的例子通过访问指定数据库表的每行记录的所有域、将每行的数据存储到String []、并将所有的行放到一个向量中,演示了标准的数据库交互过程。
public static Vector getATable(String tablename, Connection Connection)
throws SQLException
{
String sqlQuery = "SELECT * FROM " + tablename;
Statement statement = Connection.createStatement();
ResultSet resultSet = statement.executeQuery(sqlQuery);
int numColumns = resultSet.getMetaData().getColumnCount();
String[] aRow;
Vector allRows = new Vector();
while(resultSet.next())
{
aRow = new String[numColumns];
for (int i = 0; i < numColumns; i++)
file://ResultSet的访问是从1开始的,数组是从0开始的。
aRow[i] = resultSet.getString(i+1);
allRows.addElement(aRow);
}
return allRows;
}
在java.sql或其他的SDK中没有Connection、Statement和ResultSet这三个对象的具体实现,这些对象以及其他的JDBC接口都是由数据库驱动程序的厂商开发的,并被作为数据库驱动程序的一部分包括在驱动程序软件包中。假如要打印出Connection对象或使用的其他对象的类名,可能会看到类似XXXConnection、XXXStatement、XXXConnectionImpl、XXXStatementImpl等字符串,其中的XXX就是正在使用的数据库的名字,例如Oracle。
假如我们要测试例子中getATable()方法的JDBC的性能,可以简单地在该方法的开始处和末尾处添加System.currentTimeMillis(),二者之间的时间差就是getATable()方法执行所使用的时间。只要数据库的交互过程与其他过程没有搅和在一起,就可以使用这种方法测试一个方法的JDBC性能。但通常情况下,Java应用程序的的数据库交互过程分布在许多类的许多方法中,而且很难将数据库交互过程单独分离出来。那么在这种情况下我们应该如何测试数据库交互过程的性能呢?
一个理想的方法是在所有的JDBC类中都内置测量性能的能力,然后可以在需要对其性能进行监测时简单地打开监测功能就可以了。正常情况下,JDBC类没有提供这种能力,但我们可以使用具备这种功能的类来替换它们,我们替换类的目标是提供与PRoxy非常相似的对象。
使用一个接口的专用封装对象封装该接口的对象是一种有多种用途的成熟技术,collection类同步的封装对象就是最闻名的一个例子,但还有其他许多用途。SDK中甚至有一个专门在运行时才生成封装对象的类:java.lang.reflect.Proxy类。封装对象也被称作代理对象,假如在本篇文章中使用代理对象这个术语,会使对封装JDBC对象的解释更复杂,因此,在本篇文章中仍然会坚持使用封装类。
要在上述功能的基础上添加测试数据库交互过程的功能,还需要对应用程序的其他部分作一些改变,很明显的是,这样作需要一定的代价。
幸运的是,当一个框架象JDBC那样几乎完全采用接口来定义时,要用另外的实现替换其中的作一个类就相当简单了。我们可以使用一个封装类替换一个接口的任何一种实现,该封装类封装原有的类,并转发所有对原来类的方法的调用。在本篇文章中,我们可以使用一个封装类替换掉JDBC类,将我们监测JDBC性能的功能放置在封装类中,然后使监测功能随整个应用程序的执行而执行。
封装Connection类
我们将首先讨论Connection类的封装。下面的ConnectionWrapper类实现了Connection类,该类有一个Connection类的实例变量和使用构建器的参数初始化实例变量的构建器,大多数的Connection类的方法被简单地定义为将调用托付给实例变量:
赞助商链接