0

我正在尝试使用 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,我检查了数据库块是否有值。根据spiritwalker的回答,因为它没有抛出nullpointer异常,所以转换是正确的,如果那是错误的,你有什么建议作为BeanProcessor的替代品?

4

2 回答 2

1

你能确定对应的地址记录在block列中有数据吗?之所以这样想是因为,您说输出为 null而不是NullPointerException,这意味着地址已由 BeanProcessor 正确映射和初始化,否则 emp.getAddress() 应该给您一个 Null 然后 emp.getAddress().getBlock () 会以 NPE 告终吗?

而且,根据 BeanProcessor JAVA doc ** 如果转换失败(即属性是 int 并且列是 Timestamp)抛出 SQLException **,看起来转换没有任何问题。

于 2013-02-20T05:54:49.350 回答
1

BeanProcessor 文档

将 ResultSet 行转换为 JavaBean。此实现使用反射和 BeanInfo 类将列名与 bean 属性名匹配。属性与基于几个因素的列匹配:

  1. 该类具有与列同名的可写属性。名称比较不区分大小写。
  2. 可以使用 ResultSet.get* 方法将列类型转换为属性的设置方法参数类型。如果转换失败(即属性是 int 并且列是 Timestamp),则抛出 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.
        }
    }
}
于 2013-02-20T05:50:56.483 回答