2014-10-26 104 views
1

我想知道如何使用PreparedStatementCreatorFactory。至於我read它像下面的代碼,除了在罕見的例子不僅sql給工廠,但也是一個int []類型,但我不想傳遞數以百計的類型,因爲jdbc通常如果將params作爲object []傳遞,則基於java類型檢索類型。我正在使用Spring 3.1.3 RELEASE。Spring JDBC PreparedStatementCreator無效Api使用

public int addEntityAndGetId(String name, String address){ 
     String sql = "INSERT INTO mytable (NAME,ADDRESS) VALUES (?,?)"; 
     Object[] params = new Object[]{name,address}; 
     PreparedStatementCreatorFactory factory = new PreparedStatementCreatorFactory(sql); 
     PreparedStatementCreator psc = factory.newPreparedStatementCreator(params); 
     KeyHolder generatedKeyHolder = new GeneratedKeyHolder(); 

     jdbcTemplate.update(psc, generatedKeyHolder); 
     return generatedKeyHolder.getKey().intValue(); 
    } 

但我得到的是一個org.springframework.dao.InvalidDataAccessApiUsageException。

我真的需要類型嗎?就像在每個jdbc更新語句中一樣,你只需傳遞一個對象[]和它的罰款。

這個問題的目的是爲了避免需要指定任何列類型,並通過讓jdbc確定哪個列類型適合哪個對象來避免PreparedStatementSetters在crud查詢上。

+1

您是否真的閱讀過堆棧跟蹤?它是一個'ClassNotFoundException',因此你在類路徑中缺少一個jar文件。你缺少spring-tx。 – 2014-10-27 06:54:26

+0

@ M.Deinum感謝您指出。我會解決這個問題。雖然這不能解決問題。問題是爲什麼這個聲明不起作用?我怎麼能得到它的工作,如果可能的話,沒有指定列類型? – gantners 2014-10-27 10:10:40

+0

該語句應該包含與參數相同數量的佔位符。單一?如果您有多個參數,將不起作用。 – 2014-10-27 10:57:49

回答

1

您有2個不同的錯誤。一個症狀和一個原因。

首先出現症狀:您得到ClassNotFoundException: org.springframework.dao.InvalidDataAccessApiUsageException,因爲您在類路徑中缺少spring-tx,正如M.Deinum所述。添加它,因爲如果你不這樣做,你會遇到麻煩。

接下來的原因。您使用new PreparedStatementCreatorFactory(sql);創建工廠。 javadoc說:創建一個新工廠。是否需要通過addParameter(org.springframework.jdbc.core.SqlParameter)方法添加參數,或者沒有參數

你聲明的參數既不在PreparedStatementCreatorFactory的構造函數,也沒有在調用newPreparedStatementCreator()類型。所以Spring會發出異常。

不,你不能簡單地傳遞一個Object[]爲更新語句,因爲基礎JBDC調用需要的實際類型的對象(有setIntsetString,......方法)。

現在進行修復。當你將通過2串到更新方法,你應該建立工廠是這樣的:

PreparedStatementCreatorFactory factory = new PreparedStatementCreatorFactory(sql, 
    new int[]{Types.VARCHAR, Types.VARCHAR}); 

(假設列的類型爲VARCHAR

但是這還不夠。當你想回到新插入的行生成的主鍵,你必須把它聲明:最後

factory.setReturnGeneratedKeys(true); 

而且,如果你使用PosgreSQL,你可以有使用

generatedKeyHolder.getKeys().get("id"); 

代替只需​​(假設包含生成密鑰的列的名稱是id

+0

好了,截至目前可以傳遞一個對象[]到jdbctemplate並且jdbc在不指定列類型的情況下執行映射本身。你知道這是否也可以通過使用creatorfactory嗎? – gantners 2014-10-27 15:30:16

+0

AFAIK,根據javadoc(以及您當前的問題...)我的答案是否定的:您必須在工廠的構造函數中傳遞參數類型。 – 2014-10-27 15:58:24

相關問題