2012-05-11 19 views
0

嗯,我有這種方法,我不知道如何處理它的一部分,它是評論以驚歎號開頭的地方:「// !!! !這是關注我的部分......「需要關於抽象方法調用方法和字段的一些提示

public Person getPersonFromRS(ResultSet rs) throws SQLException, NoSuchMethodException, 
    IllegalAccessException, IllegalArgumentException, InvocationTargetException 
{ 
    Person person = new Person(); 

    // getting the fiels and methods of the class Person 
    Field[] fields = person.getClass().getDeclaredFields(); 
    Method[] methods = Person.class.getClass().getDeclaredMethods(); 
    String setter = "set"; 

    // just ignoring these fields of the class 
    for (Field field : fields) { 
    if (field.getName().equals("nul") || field.getName().equals("pairMarriages") 
     || field.getName().equals("pairMarriage_Date") || field.getName().equals("pairBiography")) { 
     continue; 
    } 

    // getting the value from resultSet as string 
    String value = ""; 
    try { 
     value = rs.getString(field.getName()); 
    } catch (Exception e) { 
     System.err.println("Error with getting the column " + field.getName() + " from database"); 
     continue; 
    } 

    // if value is not null and the string inside not NULL, set the value to the person 
    if (!(value == null)) 
     System.out.println("THE RETRIEVED VALUE: " + value); 

    if ((!(value == null)) && !value.equals(nul)) { 
     // methodName = setParameter 
     String methodName = setter + field.getName(); 
     System.out.println("\nmethod Name: " + methodName); 

     Method method = null; 
     try { 
     System.out.println("The field type is " + field.getType()); 
     method = person.getClass().getDeclaredMethod(methodName, field.getType()); 
     } catch (Exception e) { 
     System.err.println(e); 
     continue; 
     } 

     // !!!! this is the part that concerns me, what's the best way to handle this part in order 
     // to avoid this flood for every type? 
     // determining the type of the value to set in 
     Type type = field.getType(); 
     if (field.getType() == String.class) { 
     method.invoke(person, value); 
     } else if (field.getType() == long.class) { 
     method.invoke(person, Long.parseLong(value)); 
     } else if (field.getType() == int.class) { 
     method.invoke(person, Integer.parseInt(value)); 
     } else if (field.getType() == PersonDate.class) { 
     PersonDate date = new PersonDate(value); 
     method.invoke(person, date); 
     } 
    } 
    } 
    return person; 
} 

是否有一種最佳方式來做到這一點,而無需像這樣處理每一個參數類型?我的意思是這對我來說似乎是開銷?

+2

*「這對我來說似乎是開銷?」*對於探查器看起來如何? –

+1

可能是時候使用JPA(Java持久性API)了? JPA提供數據庫值到Java對象的自動映射。 –

回答

1

一個switch語句會更乾淨,但除非你想扔在一個真正的ORM解決方案,如JDO,JPA,休眠,無論你..你將不得不這樣做。你關心什麼?如果當你說「開銷」是指CPU週期時,那麼你應該更關心你正在做的所有反射,而不是一堆if/else語句。如果你關心的是維護,是的,這將是很多代碼。也就是說,如果你只映射了十幾種類型的話......這不是什麼大不了的事情。除了使用現成的ORM工具之外,這裏沒有任何快捷方式。

+0

對不起,這次我的意思是我的開銷。 ;)非常感謝你們所有人,出色的答案向我展示了我可能會在下次遇到像這樣的任務時使用的路徑。 另一個問題 - 難道在CPU上的反思? –

+0

它們當然不容易......但它都是相對的。 Groovy等動態語言廣泛使用反射,就像Spring一樣。對於Spring來說,它主要是在應用程序的開始時間,所以它在運行時並不明顯。隨着groovy,這是它比香草java慢得多的原因之一。 –

1

您可以先從ResultSet建立地圖。此map包含列名及其相應的值。

Map<String, String> map = new HashMap<>(); 
ResultSetMetaData metaData = rs.getMetaData(); 
int columnCount = metaData.getColumnCount(); 
for (int column = 1; column <= columnCount; column++) { 
    map.put(metaData.getColumnName(column), rs.getString(column)); 
} 
return map; 

那麼你可以使用這個mappopulatePerson一個實例。這將需要使用方法BeanUtils類,它是Apache Commons BeanUtils的一部分。

Person person = new Person(); 
BeanUtils.populate(person, map); 

這個類有:

用於經由反射填充JavaBeans屬性實用方法。

您可以根據需要修改您的查詢以填寫所需的字段。