亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

如何測定JDBC的性能(上)

2019-11-18 12:39:52
字體:
來源:轉載
供稿:網友

  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類的方法被簡單地定義為將調用托付給實例變量:
  package tuning.jdbc;
  import java.sql.*;
  import java.util.Map;
  public class ConnectionWrapper implements Connection
  {
  protected Connection realConnection;
  public Connection realConnection () {
  return realConnection;
  }
  public ConnectionWrapper (Connection Connection) {
  realConnection = Connection;
  }
  public void clearWarnings() throws SQLException {
  realConnection.clearWarnings();
  }
  public void close() throws SQLException {
  realConnection.close();
  }
  public boolean isClosed() throws SQLException {
  return realConnection.isClosed();
  }
  public void commit() throws SQLException {
  realConnection.commit();
  }
  ...
  我省略了大部分的方法,但它們都符合下面的的模板,在需要使用從數據庫驅動程序中獲取的Connection對象的地方,我們可以簡單地使用ConnectionWrapper封裝Connection對象,而使用ConnectionWrapper對象。無論在哪里獲取了Connection對象,我們都需要在該處添加下面的二行代碼:
  Connection dbConnection = getConnectionFromDriver();
  dbConnection = new ConnectionWrapper(dbConnection);
  獲得連接是該應用程序中唯一需要改變的部分,這要求發現所有獲得一個Connection對象的調用,并對該調用進行編輯。然而,大多數的應用程序使用一個集中的代理類提供Connection對象,在這種情況下,在應用程序中使用ConnectionWrapper就非常簡單了。該代理類需要頻繁地訪問一個Connection對象池,因此在將一個Connection對象釋放回Connection對象池中時,還需要作一些額外的工作,因為Connection對象首先需要被解包,例如:
  public static void releaseConnection(Connection conn)
  {
  if (conn instanceof ConnectionWrapper)
  conn = ( (ConnectionWrapper) conn).realConnection();
  ...
  }
  我們還沒有真正地完成ConnectionWrapper類,ConnectionWrapper類中有一些方法不能簡單地托付,這些就是提供各種Statement對象的方法:
  public Statement createStatement() throws SQLException {
  return new StatementWrapper(realConnection.createStatement(), this);
  }
  public Statement createStatement(int resultSetType,
  int resultSetConcurrency) throws SQLException {
  return new StatementWrapper(
  realConnection.createStatement(resultSetType,
  resultSetConcurrency), this);
  }
  public CallableStatement prepareCall(String sql) throws SQLException {
  return new CallableStatementWrapper(
  realConnection.prepareCall(sql), this, sql);
  }
  public CallableStatement prepareCall(String sql, int resultSetType,
  int resultSetConcurrency) throws SQLException {
  return new CallableStatementWrapper(
  realConnection.prepareCall(sql, resultSetType,
  resultSetConcurrency), this, sql);
  }
  public PreparedStatement prepareStatement(String sql)
  throws SQLException {
  return new PreparedStatementWrapper(
  realConnection.prepareStatement(sql), this, sql);
  }
  public PreparedStatement prepareStatement(String sql, int resultSetType,
  int resultSetConcurrency) throws SQLException {
  return new PreparedStatementWrapper(
  realConnection.prepareStatement(sql, resultSetType,
  resultSetConcurrency), this, sql);
  }
  如上所示,我們需要定義三種Statement封裝類,另外,我們還需要為DatabaseMetaData定義一個封裝類,該封裝類必須是完備的,因為DatabaseMetaData能夠返回用來創建DatabaseMetaData的Connection對象,因此我們需要確保Connection對象是經過封裝過的,而不是我們沒有封裝過的Connection對象。
  public DatabaseMetaData getMetaData() throws SQLException {
  return new DatabaseMetaDataWrapper(
  realConnection.getMetaData(), this);
  }
  封裝statement類
  Statement、PreparedStatement和CallableStatement這三個statement類的封裝類相似:
  public class StatementWrapper implements Statement
  {
  protected Statement realStatement;
  protected ConnectionWrapper connectionParent;
  
  public StatementWrapper(Statemen

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲美腿欧美激情另类| 成人亚洲激情网| 欧美丰满少妇xxxxx| 日韩精品亚洲视频| 欧美日韩在线视频一区| 亚洲永久免费观看| 高清欧美性猛交xxxx| 欧美日韩综合视频| 亚洲天堂av图片| 97视频免费在线看| 欧美极品欧美精品欧美视频| 欧美wwwwww| 一本色道久久88综合日韩精品| 黄网站色欧美视频| 久久免费观看视频| 国产一区二区黄| 国产亚洲欧美日韩一区二区| 秋霞午夜一区二区| 国产欧美日韩中文字幕在线| 成人黄色av免费在线观看| 国产精品人成电影在线观看| 欧美久久精品一级黑人c片| 国产v综合ⅴ日韩v欧美大片| 青青草国产精品一区二区| 91久热免费在线视频| 亚洲区bt下载| 国产精品一久久香蕉国产线看观看| 欧美激情中文字幕乱码免费| 久久成人精品一区二区三区| 欧美乱大交xxxxx另类电影| 国产一区二区黄| 久久精品色欧美aⅴ一区二区| 亚洲免费电影在线观看| 久久久久久久久91| 91色在线视频| 日韩在线观看免费网站| www.亚洲男人天堂| 亚洲剧情一区二区| 日韩成人激情视频| 成人精品视频久久久久| 国产精品久久久久久一区二区| 亚洲精品国产综合久久| 欧美性猛交xxxx偷拍洗澡| 国产精品观看在线亚洲人成网| 96sao精品视频在线观看| 国产黑人绿帽在线第一区| 精品成人在线视频| 亚洲国产精品va| 国产一区二区三区免费视频| 中日韩美女免费视频网址在线观看| 色哟哟亚洲精品一区二区| 日韩高清人体午夜| 欧美极品美女视频网站在线观看免费| 国产精品久久久久久久久久小说| 一本一道久久a久久精品逆3p| 亚洲精品456在线播放狼人| 久久九九亚洲综合| 欧美一级在线亚洲天堂| 国产91精品久久久久久久| 亚洲国产成人av在线| 久久久久久久久亚洲| 欧美午夜激情视频| 亚洲深夜福利视频| 欧美黑人性生活视频| 国产精品jizz在线观看麻豆| 亚洲精品91美女久久久久久久| 日日噜噜噜夜夜爽亚洲精品| 亚洲综合国产精品| 爱福利视频一区| 中文字幕亚洲一区| 午夜精品美女自拍福到在线| 欧美午夜激情在线| 91天堂在线观看| 国产成人av在线播放| 成人97在线观看视频| 97香蕉久久超级碰碰高清版| 日韩美女主播视频| 亚洲欧美综合图区| 亚洲天堂第一页| 亚洲福利视频二区| 日韩电影大全免费观看2023年上| 欧美日韩亚洲一区二区| 日韩毛片在线看| 91精品国产高清久久久久久91| 97在线视频免费观看| 日韩高清电影好看的电视剧电影| 亚洲国产精品久久久久秋霞蜜臀| 亚洲一区二区三区久久| 成人网在线观看| 中文字幕精品久久久久| 欧美另类xxx| 欧美午夜精品久久久久久久| 亚洲国产精品99久久| 日韩精品在线免费| 狠狠爱在线视频一区| 精品视频—区二区三区免费| 精品国产精品自拍| 一本色道久久综合亚洲精品小说| 亚洲男女自偷自拍图片另类| 国产精品扒开腿爽爽爽视频| 中文字幕免费国产精品| 久久精品电影一区二区| 欧美伊久线香蕉线新在线| 精品亚洲精品福利线在观看| 国产视频福利一区| 欧美色欧美亚洲高清在线视频| 欧美日韩国产中字| 午夜精品久久久久久久久久久久| 久久精品夜夜夜夜夜久久| 亚洲网站在线播放| 国产精欧美一区二区三区| 日本一区二区不卡| 成人字幕网zmw| 国产精品久久91| 亚洲无av在线中文字幕| 国产成人av在线播放| 亚洲国产成人精品一区二区| 91国产精品视频在线| 欧美在线视频在线播放完整版免费观看| 国产亚洲精品久久| 国产精品伦子伦免费视频| 欧美亚洲一区在线| 亚洲午夜小视频| 日本精品中文字幕| 国产精品一久久香蕉国产线看观看| 亚洲精品av在线播放| 色综合老司机第九色激情| 国产精品视频白浆免费视频| 97碰在线观看| 韩国v欧美v日本v亚洲| 欧美精品videofree1080p| 欧美成人午夜激情| www.日本久久久久com.| 这里只有精品丝袜| 久久久亚洲国产天美传媒修理工| 久久九九热免费视频| 国产精品成人av在线| 成人福利免费观看| 中文字幕av一区中文字幕天堂| 欧美成人三级视频网站| 青青在线视频一区二区三区| 国产一区二区三区直播精品电影| 欧美日韩亚洲视频一区| zzjj国产精品一区二区| 精品国产福利视频| 久久天天躁夜夜躁狠狠躁2022| 亚洲成人网在线| 久久99久久99精品中文字幕| 亚洲一区av在线播放| 欧美有码在线观看| 亚洲黄页网在线观看| 欧美巨猛xxxx猛交黑人97人| 国产亚洲精品激情久久| 91中文精品字幕在线视频| 欧美亚洲激情视频| 中文字幕在线看视频国产欧美| 欧美性猛交xxxx乱大交3| 欧美另类老女人| 国产激情综合五月久久| 97国产精品免费视频| 久久成人亚洲精品| 蜜臀久久99精品久久久久久宅男| 欧美电影在线观看完整版| 国产精品久久久久久久久粉嫩av|