2014-09-24 67 views
-3

我有以下的代碼:如何使這個JDBC代碼更加便攜?

List<List<Object>> batch = db.executeInsert("insert into Batches (batch_date,source,log_file,status) values (?, ?, ?, ?)", 
    now, 
    importZip.getAbsolutePath(), 
    logFile.getAbsolutePath(), 
    BatchStatus.IMPORTING.toString()) 

而返回的數據,當我在MySQL運行它返回一個整數,表示插入的ID按預期方式。在Oracle下運行時,它將返回一個非便攜式的對象ROWID。我有一個標識列,最終將轉換爲表示ID的序列。然而,你可以用ROWID做什麼。

我檢查了代碼,我打電話給statement.getGeneratedKeys(),我認爲這是製作便攜式代碼的重點。我怎樣才能以便攜的方式編寫這個程序,而不需要執行一些明顯不便攜的東西,如select from table where ROWID=?

+0

db.executeInsert()方法在哪裏?你爲什麼要問你沒有發佈的代碼的行爲? – EJP 2014-09-24 04:55:15

回答

1

所以便攜式解決方案,我發現是使用一個稍微不同的版本,PreparedStatement和的getGeneratedKeys的() 。事實證明,這是跨越mysql和oracle的便攜式,我想其他人:

Connection connection = createConnection(); 
PreparedStatement statement = null; 
statement = connection.prepareStatement(sql,new String[] { "ID" }); 
int updateCount = statement.executeUpdate(); 

ResultSet keysRs = statement.getGeneratedKeys(); 
if(keysRs.next()) { 
    return keyRs.getInteger("ID"); 
} 

這是我使用的解決方案。

+0

我對Oracle的這個作品有些驚訝,但是很好找!由於我不知道這個功能對Oracle有效,因此我沒有在我的答案中提到它。 – 2014-09-29 09:26:12

1

正如您已經發現的那樣,Oracle返回ROWID,以便您可以 - 例如 - 通過查詢該行來獲取該id。

有些數據庫只返回最後生成的ID(這甚至可能不屬於表中,如MySQL的據我所知),某些數據庫僅返回ID列在ResultSet的第一列,其他人返回所有列(如PostgreSQL,Firebird),所以id列​​的位置可能不一定是第一個,因爲它取決於表中的列順序。

唯一真正的選擇是創建一個知道規則的數據庫特定策略以獲取正確的列。這可能涉及發射了甲骨文的額外的查詢,有一些啓發找到PostgreSQL和火鳥的主鍵列,等

+0

因此,在executeInsert()代碼的封面下,它調用getGeneratedKeys(),我認爲這是使ID檢索DB平臺獨立的機制。爲什麼它仍然要求您編寫數據庫特定的代碼來處理這種情況?如果它不這樣做那麼getGeneratedKeys()有什麼意義? – chubbsondubs 2014-09-24 19:08:22

+0

@chubbsondubs在完美的世界中,您不需要編寫特定於db的代碼,但這不是一個完美的世界,並且數據庫支持的功能存在差異。 – 2014-09-25 07:45:28