2012-05-11 5 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 Persistence API)を使用する時間がありますか? JPAはデータベース値をJavaオブジェクトに自動的にマッピングします。 –

答えて

1

switch文はより洗練されていますが、JDO、JPA、休止状態などの本当のORMソリューションをスローしたいのでなければ、何とかしなければなりません。あなたの懸念は何ですか? "オーバーヘッド"と言うとCPUサイクルを意味する場合は、if/elseステートメントではなく、実行しているすべてのリフレクションをより心配する必要があります。あなたの懸念事項がメンテナンスの場合、ええ、それは多くのコードになるでしょう。つまり、十数個程度の型しかマッピングしていないのであれば、大したことではありません。実際にORMツールを使用する以外のショートカットはありません。

+0

申し訳ありませんが、今回は私がオーバーヘッドとしてオーバーヘッドとして書いていました。 ;)皆さん、ありがとう、私が次回使用するかもしれない道を示す優れた答えは、このような仕事に遭遇します。 もう1つの質問 - CPU上のハードな反映ですか? –

+0

彼らは確かにそれで簡単ではありません...しかし、それはすべて相対的です。 groovyのような動的言語は、Springと同様に広範囲に反映されます。 Springでは、ほとんどがアプリケーションの開始時になるため、実行時にはそれほど目立つことはありません。 Groovyを使用すると、それはvanilla javaよりもはるかに遅い理由の1つです。 –

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; 

その後、Personのこのmappopulateのインスタンスを使用することができます。これには、の一部であるBeanUtilsクラスのpopulateメソッドを使用する必要があります。

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

このクラスはありますリフレクション経由でのJavaBeansのプロパティを取り込むための

ユーティリティメソッド。

必要なフィールドに入力するようにクエリを変更することができます。

関連する問題