Java 豆处理器部分工作

Java 豆处理器部分工作,java,database,jakarta-ee,Java,Database,Jakarta Ee,我试图使用BeanProcessor填充我的类,但它部分有效。 我的课程如下 地址类 public class Address { ..All attributes of address class go here... .. All setter and getters go here... } 将address类作为其成员的Employee类 public class Employee { private int ID; private Stri

我试图使用BeanProcessor填充我的类,但它部分有效。 我的课程如下

地址类

public class Address {

    ..All attributes of address class go here...
        .. All setter and getters go here...
}
将address类作为其成员的Employee类

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....
}
公共类员工{
私有int-ID;
私有字符串fname;
私有字符串名称;
私有字符串移动;
私人电话;
私人字符串电子邮件;
私有字符串位置;
私有字符串标题;
私有字符串用户名;
私有字符串密码;
私有字符串问题;
私有字符串应答;
专用地址地址;来自:

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

  • 该类具有与列同名的可写属性。名称比较不区分大小写
  • 可以将列类型转换为属性的set方法 使用ResultSet.get*方法的参数类型。如果转换失败 (即,属性为int,列为时间戳)an 将引发SQLException
  • 请注意第二点。ResultSet不支持
    Address
    类。因此,BeanProcessor无法处理此类字段

    更新:关于处理期间的SQLException

    您应该检查您的sql查询。如果它没有返回名为
    address
    的列,则BeanProcessor不会触及此属性,因此不会引发任何异常

    更新:关于NullPointerException

    是的,
    getAddress().getBlock()
    没有抛出NullPointerException,这听起来很奇怪。但是从上面的文档可以清楚地看到BeanProcessor无法正确初始化地址字段。我猜
    getAddress()
    即使不调用
    setAddress
    也会以某种方式返回非空对象。请仔细检查员工的默认构造函数和
    getAddress
    方法

    您还可以调用
    newemployee().getAddress().getBlock()
    来检查这一点

    更新:如何实现嵌套对象处理

    我没有使用BeanProcessor的经验,但它提供了一些您可以使用的受保护方法。例如,您可以尝试覆盖:

    公共类CustomBeanProcessor扩展BeanProcessor{
    @凌驾
    受保护的int[]MapColumnStorProperties(ResultSetMetaData rsmd、PropertyDescriptor[]props)引发SQLException{
    int[]mapping=super.mapcolumnstroperty(rsmd,props);
    对于(PropertyDescriptor道具:道具){
    //查找地址属性
    //将属性\u NOT \u FOUND值更改为列的索引(可能是addressid)
    }
    }
    @凌驾
    受保护对象processColumn(结果集rs、int索引、类propType)引发SQLException{
    if(propType==Address.class){
    //在这里创建地址对象
    //您可能需要多次调用rs.get以检查所有地址属性。
    }
    }
    }
    
    你能确保相应的地址记录在block列中有数据吗?这会让人产生这样的想法,因为你说的输出为null,而不是NullPointerException,这意味着地址被BeanProcessor正确映射和初始化,否则emp.getAddress()是否应该给您一个Null,然后emp.getAddress().getBlock()将以NPE结束


    此外,根据BeanProcessor JAVA文档**,如果转换失败(即,属性为int,列为时间戳)SQLException是throw**,转换似乎没有什么问题。

    这是一个更广泛的问题。BeanProcessor只能处理标准类型,因此不支持嵌套bean。因此,您可以尝试使用非嵌套普通bean将查询和/或bean增强为只读标准类型(例如,直接在employee类中阻止名称)。您也可以尝试分别处理地址和员工,然后以某种方式将它们链接在一起。Google query将我带到我建议您查看的位置,而不是实现自己的ORM框架。NPE是一个公平的问题。您可以检查调用
    (新员工()).getAddress().getBlock();
            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;
        }
    
    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.
            }
        }
    }