6

我想知道社区认为关于使用 Spring JDBC 映射类层次结构的“最佳实践”。

我们没有能力使用成熟的 ORM 工具,但是我们正在使用 Spring JDBC 来减轻 JDBC 的一些繁琐性质。我们经常使用的一类是 BeanPropertyRowMapper,因为它易于使用,并且能够从我们的结果集中访问类型不敏感的 bean 属性。

我有一个类层次结构,它都映射回单个表(对这个小类层次结构采用 table-per-hiearchy 方法)。因此,该表包含一个 classId 列,可用于确定应实际实例化的类。前任。1 = 经理,2 = 员工,3 = 承包商。所有这些都是“人”,但每个人的子类都有一些属性是他们的类所独有的。

我最初的想法是创建一个 BeanPropertyRowMapper 的子类并尝试注入这个逻辑来表示“如果列 A = 1 然后实例化一个 Manager,然后进行正常绑定”。

这看起来是一种合理的方法吗?人们是否有其他对您有用的建议?

4

2 回答 2

4

看起来子类中没有一个地方可以添加一个钩子来切换类,而无需完全复制 BeanPropertyRowMapper 的 mapRow() 实现。您最好的方法可能是创建一个 RowMapper 类,该类委托给适当的 BeanPropertyRowMapper。

例如:

    final RowMapper managerMapper = new BeanPropertyRowMapper(Manager.class);
    final RowMapper employeeMapper = new BeanPropertyRowMapper(Employee.class);
    final RowMapper contractorMapper = new BeanPropertyRowMapper(Contractor.class);

    RowMapper rm = new RowMapper()
    {
        @Override
        public Object mapRow(ResultSet rs, int rowNum)
            throws SQLException
        {
            int employeeType = rs.getInt("type");
            switch (employeeType)
            {
                case 1:
                    return managerMapper.mapRow(rs, rowNum); 

                case 2:
                    return employeeMapper.mapRow(rs, rowNum);

                case 3:
                    return contractorMapper.mapRow(rs, rowNum);

                default:
                    break;

            }
        }
    };
于 2009-12-02T20:00:21.257 回答
1

我不确定这是“最佳实践”,但我建议采用以下方法(不使用 bean 属性--> 应该更快)。

通常你知道你期望检索什么样的对象。所以你可以在执行 sql 时提供相应的行映射器。

声明自定义抽象通用 RowMapper 并为每种类型的人创建自己的行映射器,即:

private static abstract class PersonRowMapper<T extends Person> implements RowMapper<T> {

 @Override
 public abstract T mapRow(ResultSet rs, int rowNum) throws SQLException;

 protected void mapBase(ResultSet rs, T person) throws SQLException {
  //base mapping here
 }
}


private static class EmployeeRowMapper extends PersonRowMapper<Employee> {

 @Override
 public Employee mapRow(ResultSet rs, int rowNum) throws SQLException {
  Employee e = new Employee();
  mapBase(rs, e);
  //set other specific employee props
 }
}

通过其他方法,您可以在基本映射器中为特定道具声明抽象方法,即

private static abstract class PersonRowMapper<T extends Person> implements RowMapper<T> {
 @Override
 public T mapRow(ResultSet rs, int rowNum) throws SQLException {
  T instance = getInstance();
  //set base props here
  fill(rs, instance);
 }

 //e.g. return new Employee()
 protected abstract T getInstance();
 //fill specific instance props
 protected abstract void fill(ResultSet rs, T instance) throws SQLException;
}
于 2014-11-11T12:57:29.367 回答