我正在尝试使用BeanProcessor填充我的类,但它部分有效。 我的课程如下
地址类
public class Address {
..All attributes of address class go here...
.. All setter and getters go here...
}
具有地址类作为其成员的员工类
public class Employee {
private int ID;
private String fname;
private String lname;
private String mobile;
private String phone;
private String email;
private String position;
private String title;
private String username;
private String password;
private String question;
private String answer;
private Address address; << address class is a member of employee class
.. All setter and getters go here....
}
我的模型如下:
Employee emp = new Employee();
try {
ps = con.prepareStatement("select * from employee,address "
+ "WHERE employee.username = ? AND "
+ "employee.AddID = address.ID");
ps.setString(1, username);
ResultSet r = ps.executeQuery();
if (r.next()) {
BeanProcessor bp = new BeanProcessor();
emp = bp.toBean(r,Employee.class);
System.out.println("name:" + emp.getName()); << shows the name correctly
System.out.println("block:"+emp.getAddress().getBlock());<< the output is null
}
con.close();
ps.close();
} catch (SQLException e) {
System.err.println(e.getMessage());
}
return emp;
}
当我运行应用程序时,它显示emp对象被正确填充但其中的Address对象没有,并且它为getBlock()方法返回null,我检查了数据库块有一个值。根据灵魂行者的回答吹,因为它没有抛出nullpointer异常转换是完全正确的,如果那是错的,你的建议是什么作为BeanProcessor的替代?
答案 0 :(得分:1)
您能确保相应的地址记录确实包含阻止列中的数据吗?它是这样想的,因为你说输出为空而不是 NullPointerException ,这意味着地址被BeanProcessor正确映射和初始化,否则emp.getAddress()应该给你一个Null,然后emp.getAddress()。getBlock()将以NPE结束?
而且,根据BeanProcessor JAVA doc **如果转换失败(即属性是一个int而列是一个时间戳),则抛出一个SQLException **,它看起来不像转换有什么问题
答案 1 :(得分:0)
来自BeanProcessor documentation:
将ResultSet行转换为JavaBean。此实现使用反射和BeanInfo类将列名称与bean属性名称匹配。根据以下几个因素将属性与列匹配:
- 该类具有与列相同名称的可写属性。名称比较不区分大小写。
- 列类型可以转换为属性的set方法 带有ResultSet.get *方法的参数类型。如果转换失败 (即属性是一个int,列是一个时间戳) 抛出SQLException。
醇>
注意第二点。 ResultSet不支持Address
类。因此,BeanProcessor无法处理此类型的字段。
更新:关于处理期间的SQLException。
你应该检查你的SQL查询。如果它不返回名为address
的列,则BeanProcessor不会触及此属性,因此不会抛出任何异常。
更新:关于NullPointerException。
是的,getAddress().getBlock()
不会抛出NullPointerException听起来很奇怪。但是从上面的文档中可以清楚地看出,BeanProcessor无法正确初始化地址字段。我的猜测是,即使没有getAddress()
调用,setAddress
也会以某种方式返回非空对象。请仔细检查Employee的默认构造函数和getAddress
方法。
您也可以致电new Employee().getAddress().getBlock()
进行检查。
更新:如何实现嵌套对象处理
我没有使用BeanProcessor的经验,但它提供了一些您可以使用的受保护方法。例如,您可以尝试覆盖processColumn:
public class CustomBeanProcessor extends BeanProcessor {
@Override
protected int[] mapColumnsToProperties(ResultSetMetaData rsmd, PropertyDescriptor[] props) throws SQLException {
int[] mapping = super.mapColumnsToProperties(rsmd, props);
for(PropertyDescriptor prop : props) {
//find address property
//change PROPERTY_NOT_FOUND value to index of column (addressid maybe)
}
}
@Override
protected Object processColumn(ResultSet rs, int index, Class<?> propType) throws SQLException {
if(propType==Address.class) {
//here you create address object
//you may need several calls to rs.get to check for all address properties.
}
}
}