免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
批處理JDBC語句以提高處理速度
有的時(shí)候JDBC運(yùn)行的不夠理想,這就促使我們寫一些與特定數(shù)據(jù)庫相關(guān)的存儲(chǔ)過程。作為一個(gè)替換方案,不妨試一下Statement的批處理特征,看看一次執(zhí)行所有的SQL語句是否會(huì)帶來速度的提升。

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

使用批處理功能涉及到兩個(gè)方法:

addBatch(String)方法
executeBatch方法
addBatch方法可以接受一段標(biāo)準(zhǔn)的SQL(如果你使用一個(gè)Statement)作為參數(shù),也可以什么參數(shù)都不帶(如果你使用一個(gè)PreparedStatement)。

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

下面是一個(gè)簡(jiǎn)單的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會(huì)稍有不同。它只能處理一段SQL語句,但可以帶很多參數(shù)。下面的是使用PreparedStatement重寫的上面的例子:

//注意我們并沒有做任何刪除動(dòng)作

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í)行次數(shù)的SQL代碼的一個(gè)好方法。沒有批處理,如果要添加50個(gè)用戶,其性能可能受到影響。如果誰寫了一段添加10000個(gè)用戶的腳本,其運(yùn)行速度就難以忍受。增加批處理將有助于提升性能,在后一種情況里,甚至可以改善代碼的可讀性。



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

JDBC(Java Database Connectivity,java數(shù)據(jù)庫連接)的API中的主要的四個(gè)類之一的java.sql.Statement要求開發(fā)者付出大量的時(shí)間和精力。 在使用Statement獲取JDBC訪問時(shí)所具有的一個(gè)共通的問題是輸入適當(dāng)格式的日期和時(shí)間戳:2002-02-05 20:56 或者 02/05/02 8:56 PM。通過使用java.sql.PreparedStatement,這個(gè)問題可以自動(dòng)解決。一個(gè)PreparedStatement是從 java.sql.Connection對(duì)象和所提供的SQL字符串得到的,SQL字符串中包含問號(hào)(?),這些問號(hào)標(biāo)明變量的位置,然后提供變量的值, 最后執(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的另一個(gè)優(yōu)點(diǎn)是字符串不是動(dòng)態(tài)創(chuàng)建的。下面是一個(gè)動(dò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.2mdn.net/1280511/SCH_300x250_v02.gif" BORDER=0&gt;&lt;/A&gt; &lt;A TARGET="_top" &gt;&lt;IMG SRC="http://m2.cn.doubleclick.net/714347/10gdata_336x280.gif" BORDER=0&gt;&lt;/A&gt;

這允許JVM(JavaVirtual Machine,Java虛擬機(jī))和驅(qū)動(dòng)/數(shù)據(jù)庫緩存語句和字符串并提高性能。

PreparedStatement也提供數(shù)據(jù)庫無關(guān)性。當(dāng)顯示聲明的SQL越少,那么潛在的SQL語句的數(shù)據(jù)庫依賴性就越小。

由于PreparedStatement具備很多優(yōu)點(diǎn),開發(fā)者可能通常都使用它,只有在完全是因?yàn)樾阅茉蚧蛘呤窃谝恍蠸QL語句中沒有變量的時(shí)候才使用通常的Statement。


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

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

Example 31-1. 在 JDBC 里處理一個(gè)簡(jiǎn)單的查詢

這個(gè)例子將發(fā)出一個(gè)簡(jiǎn)單的查詢?nèi)缓笥靡粋€(gè) Statement打印出每行的第一個(gè)字段。

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();

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

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. 使用 Statement或 PreparedStatement 接口

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

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

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

  • 如果你使用了 threads (線程),并且有幾個(gè)使用數(shù)據(jù)庫, 你對(duì)每個(gè)線程必須使用一個(gè)獨(dú)立的 Statement。 如果考慮使用線程, 請(qǐng)參考本文檔稍后的 Section 31.8 章節(jié), 因?yàn)檫@些內(nèi)容包含一些重要的信息。

  • 在你用完 Statement 或者 PreparedStatement 之后,你應(yīng)該關(guān)閉它。

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

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

  • 在讀取任何數(shù)值的時(shí)候,你必須調(diào)用 next()。 如果還有結(jié)果則返回真(true),但更重要的是,它為處理準(zhǔn)備了數(shù)據(jù)行。

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

  • 一旦你結(jié)束對(duì)一個(gè) ResultSet 的處理,你必須對(duì)之調(diào)用 close()來關(guān)閉它。

  • 一旦你使用那個(gè)創(chuàng)建 ResultSetStatement做另一個(gè)查詢請(qǐng)求, 當(dāng)前打開的 ResultSet 實(shí)例將自動(dòng)關(guān)閉。

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

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Java的數(shù)據(jù)庫連接編程(JDBC)技術(shù)
java使用MySQL學(xué)習(xí)
java_JDBC編程
addBatch的用法
JDBC系列教程(三)---語句
JDBC常見面試題集錦
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服