2013-06-29 50 views
4

我需要檢索ResultSet中的值以通過反射來調用構造函數。 我正在嘗試Class.cast(Object),但我總是得到一個InvalidCastException如何一般從ResultSet獲取值?

這是我有:

Object[] args = new Object[count]; 
    Class<?>[] arr = co.getParameterTypes(); 
    for(i = 0; i<args.length; i++){ 

     args[i] = arr[i].cast(rs.getObject(i+1)); 
    } 

    Object t; 

    try { 
     t = co.newInstance(args); 
    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 

    return (T)t; 

合作是構造函數,RS是ResultSet我已經有了。

+1

你能否提供更多的上下文?該表,SQL選擇和/或「co」的類? – acdcjunior

+0

這是爲動態代理創建通用轉換器的上下文。該轉換器會將ResultSet轉換爲他知道的域實體。我們目前正在與Northwind一起嘗試此操作,並且該表格可以是該數據庫中的任何一個。在我們的應用程序中,構造函數類可以是Northwind的任何域實體。 –

+0

所以'co'可以有效的任何階級,這是你的意思嗎? – acdcjunior

回答

1

即使您可以得到這個工作,但長期維護的噩夢是Object的構造函數中參數的順序可能與ResultSet(RDB中的表)的列順序不匹配。例如,如果您的Person對象具有采用firstName,lastName的構造函數,那麼數據庫表中列的順序可能不匹配。它可以是LAST_NAME,FIRST_NAME,甚至可以是FIRST_NAME,SOME_COLUMN_YOU_DONT_CARE_ABOUT,LAST_NAME。

在代碼中,我已經看到更一般地處理這個問題,他們使用對域對象(例如Person)的反射來獲取屬性名稱(在我的情況下,他們看着setter,而不是構造函數,YMMV),然後嘗試以使其與ResultSet列名匹配,使用ResultSet.getMetaData()

+0

我們幾乎涵蓋了這一部分,現在唯一真正的問題是實際能夠通過getObject方法從ResultSet中獲取「事物」,然後將這些對象作爲參數傳遞給構造函數。由於SQL類型系統與Java中的不同,我們將始終有一個CastException。我們如何做到這一點,而不使用ResultSet的getString,getInt,getDouble等.....方法。 –

+0

我認爲你需要在Java類型和SQL類型getInt,getDouble等之間有一系列if/else語句(或開關)映射......但是因爲它都在一箇中心位置,它會爲你節省很多的痛苦。 – user949300

+0

你也可以編寫你自己的對應於java.sql.Types的枚舉,這允許這樣做是一個相當乾淨的O-O方式。 Oracle for Java 9的注意事項:請製作java.sql.Types的枚舉版本! – user949300