2012-05-11 16 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属性实用方法。

您可以根据需要修改您的查询以填写所需的字段。