一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

批處理JDBC語句以提高處理速度

 小朋 2006-11-02
有的時候JDBC運行的不夠理想,這就促使我們寫一些與特定數據庫相關的存儲過程。作為一個替換方案,不妨試一下Statement的批處理特征,看看一次執(zhí)行所有的SQL語句是否會帶來速度的提升。

存儲過程最簡單的形式就是整個過程只包含一組SQL語句。將這些語句放到一起能容易管理也可以提高運行速度。Statement類具有包含一串SQL語句的能力,因此它允許所有的SQL語句在一個數據庫會話中被執(zhí)行,從而避免了向數據庫進行一連串的執(zhí)行調用。

使用批處理功能涉及到兩個方法:

addBatch(String)方法
executeBatch方法
addBatch方法可以接受一段標準的SQL(如果你使用一個Statement)作為參數,也可以什么參數都不帶(如果你使用一個PreparedStatement)。

executeBatch方法接著執(zhí)行SQL語句,返回一個int型數組。這個數組包括每條語句影響到的行數。如果在一個批處理中使用是一個SELECT或者其它只返回結果的語句,那么將會產生一個SQLException異常。

下面是一個簡單的java.sql.Statement的例子:

Statement stmt = conn.createStatement();
stmt.insert("DELETE FROM Users");
stmt.insert("INSERT INTO Users VALUES(‘rod‘, 37, ‘circle‘)");
stmt.insert("INSERT INTO Users VALUES(‘jane‘, 33, ‘triangle‘)");
stmt.insert("INSERT INTO Users VALUES(‘freddy‘, 29, ‘square‘)");

int[] counts = stmt.executeBatch();

使用PreparedStatement會稍有不同。它只能處理一段SQL語句,但可以帶很多參數。下面的是使用PreparedStatement重寫的上面的例子:

//注意我們并沒有做任何刪除動作

PreparedStatement stmt = conn.prepareStatement( _
"INSERT INTO Users VALUES(?,?,?)" );
User[ ] users = ...;
for(int i=0; i<users.length; i++)

{
stmt.setInt(1, users[i].getName());
stmt.setInt(2, users[i].getAge());
stmt.setInt(3, users[i].getShape());
stmt.addBatch( );
}
int[ ] counts = stmt.executeBatch();

這是處理那些不知道具體執(zhí)行次數的SQL代碼的一個好方法。沒有批處理,如果要添加50個用戶,其性能可能受到影響。如果誰寫了一段添加10000個用戶的腳本,其運行速度就難以忍受。增加批處理將有助于提升性能,在后一種情況里,甚至可以改善代碼的可讀性。



使用PreparedStatement減少開發(fā)時間

JDBC(Java Database Connectivity,java數據庫連接)的API中的主要的四個類之一的java.sql.Statement要求開發(fā)者付出大量的時間和精力。 在使用Statement獲取JDBC訪問時所具有的一個共通的問題是輸入適當格式的日期和時間戳:2002-02-05 20:56 或者 02/05/02 8:56 PM。通過使用java.sql.PreparedStatement,這個問題可以自動解決。一個PreparedStatement是從 java.sql.Connection對象和所提供的SQL字符串得到的,SQL字符串中包含問號(?),這些問號標明變量的位置,然后提供變量的值, 最后執(zhí)行語句,例如:
Stringsql = "SELECT * FROM People p WHERE p.id = ? AND p.name = ?";

PreparedStatement ps = connection.prepareStatement(sql);

ps.setInt(1,id);

ps.setString(2,name);

ResultSet rs = ps.execute();

使用PreparedStatement的另一個優(yōu)點是字符串不是動態(tài)創(chuàng)建的。下面是一個動態(tài)創(chuàng)建字符串的例子:
Stringsql = "SELECT * FROM People p WHERE p.i = "+id; 

&lt;A TARGET="_top" &gt;&lt;IMG SRC="http://m.cn./1280511/SCH_300x250_v02.gif" BORDER=0&gt;&lt;/A&gt; &lt;A TARGET="_top" &gt;&lt;IMG SRC="http://m2.cn./714347/10gdata_336x280.gif" BORDER=0&gt;&lt;/A&gt;

這允許JVM(JavaVirtual Machine,Java虛擬機)和驅動/數據庫緩存語句和字符串并提高性能。

PreparedStatement也提供數據庫無關性。當顯示聲明的SQL越少,那么潛在的SQL語句的數據庫依賴性就越小。

由于PreparedStatement具備很多優(yōu)點,開發(fā)者可能通常都使用它,只有在完全是因為性能原因或者是在一行SQL語句中沒有變量的時候才使用通常的Statement。


發(fā)出查詢和處理結果

在任何你想向數據庫運行一個SQL語句的時候, 你都需要一個 StatementPreparedStatement 實例。 一旦你擁有了一個 StatementPreparedStatement,你就可以 發(fā)出一個查詢。 這樣將返回一個 ResultSet 實例, 在其內部包含整個結果。 Example 31-1 演示了這個過程。

Example 31-1. 在 JDBC 里處理一個簡單的查詢

這個例子將發(fā)出一個簡單的查詢然后用一個 Statement打印出每行的第一個字段。

Statement st = db.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM mytable WHERE columnfoo = 500");
while (rs.next()) {
System.out.print("Column 1 returned ");
System.out.println(rs.getString(1));
}
rs.close();
st.close();

這個例子將使用 PreparedStatement 發(fā)出和前面一樣的查詢,并且在查詢中制作數值。

int foovalue = 500;
PreparedStatement st = db.prepareStatement("SELECT * FROM mytable WHERE columnfoo = ?");
st.setInt(1, foovalue);
ResultSet rs = st.executeQuery();
while (rs.next()) {
System.out.print("Column 1 returned ");
System.out.println(rs.getString(1));
}
rs.close();
st.close();

31.3.1. 使用 StatementPreparedStatement 接口

在使用 StatementPreparedStatement接口時必須考慮下面的問題:

  • 你可以將一個 StatementPreparedStatement實例使用任意次。 你可以在打開一個聯接后馬上創(chuàng)建一個 Statement 實例, 并且在聯接的生存期里使用之。 你必須記住每個 StatementPreparedStatement只能存在一個 ResultSet。

  • 如果你需要在處理一個 ResultSet的時候執(zhí)行一個查詢, 你只需要創(chuàng)建并且使用另外一個 Statement。

  • 如果你使用了 threads (線程),并且有幾個使用數據庫, 你對每個線程必須使用一個獨立的 Statement。 如果考慮使用線程, 請參考本文檔稍后的 Section 31.8 章節(jié), 因為這些內容包含一些重要的信息。

  • 在你用完 Statement 或者 PreparedStatement 之后,你應該關閉它。

31.3.2. 使用 ResultSet(結果集)接口

使用 ResultSet接口時必須考慮下面的問題:

  • 在讀取任何數值的時候,你必須調用 next()。 如果還有結果則返回真(true),但更重要的是,它為處理準備了數據行。

  • 在 JDBC 規(guī)范里,你對一個字段應該只訪問一次。 遵循這個規(guī)則是最安全的,不過目前 PostgreSQL 驅動將允許你對一個字段訪問任意次。

  • 一旦你結束對一個 ResultSet 的處理,你必須對之調用 close()來關閉它。

  • 一旦你使用那個創(chuàng)建 ResultSetStatement做另一個查詢請求, 當前打開的 ResultSet 實例將自動關閉。

  • 目前的 ResultSet 是只讀的。 你不能通過 ResultSet 來更新數據。 如果你想更新數據,那么你就需要使用普通的方法來做∶ 通過發(fā)出一條 SQL 更新語句。這么做是和 JDBC 規(guī)范兼容的,它并不要求驅動提供可更新的結果集的支持。

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發(fā)現有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    极品少妇一区二区三区精品视频| 丝袜诱惑一区二区三区| 久久精品久久精品中文字幕| 丰满少妇被粗大猛烈进出视频| 国产一级内片内射免费看| 亚洲国产精品一区二区毛片| 午夜精品福利视频观看| 午夜精品麻豆视频91| 日本人妻精品有码字幕| 中日韩免费一区二区三区| 国产一级内射麻豆91| 国产精品日韩欧美一区二区| 欧美av人人妻av人人爽蜜桃| 久久精视频免费视频观看| 日韩人妻毛片中文字幕| 国内真实露脸偷拍视频| 国产丝袜女优一区二区三区| 日本视频在线观看不卡| 99少妇偷拍视频在线| 国产精品国三级国产专不卡| 99一级特黄色性生活片| 99久免费精品视频在线观| 国产成人午夜av一区二区| 日韩人妻一区中文字幕| 色婷婷中文字幕在线视频| 亚洲中文字幕视频在线播放| 中文字幕亚洲精品人妻| 国产一区二区三区成人精品| 久久永久免费一区二区| 老司机精品一区二区三区| 国产一区二区三区香蕉av| 日本国产欧美精品视频| 又黄又爽禁片视频在线观看| 欧美日韩亚洲国产av| 国产一区二区三区不卡| 亚洲一区二区三区日韩91| 婷婷九月在线中文字幕| 亚洲精品中文字幕欧美| 国产精品欧美日韩中文字幕| 高清不卡一卡二卡区在线| 国产亚洲系列91精品|