2009-12-02 32 views
5

我想知道社區如何將Spring類的層次結構映射到「最佳實踐」。具有類Hiearchies的Spring RowMapper

我們沒有能力使用完整的ORM工具,但是我們正在使用Spring JDBC來減輕JDBC的一些單調乏味的特性。我們經常使用的一個類是BeanPropertyRowMapper,因爲它易於使用,並且能夠從結果集中訪問對類型不敏感的bean屬性。

我有一個類層次結構,所有的都映射回單個表(對於這個小的類層次結構採取table-per-hiearchy方法)。因此,該表包含一個classId列,可用於確定實際應該實例化哪個類。防爆。 1 =經理,2 =員工,3 =承包商。所有這些都是「人」,但每個人的子類都有一些屬於他們班級的特性。

我最初的想法是創建一個BeanPropertyRowMapper的子類,嘗試並注入這個邏輯來說「如果A列= 1,然後實例化一個管理器,然後做你的nomral綁定」。

這似乎是一個合理的方法嗎?有沒有其他建議可能會爲你工作?

預先感謝您的答覆,

賈斯汀N.

回答

4

它看起來並不像有子類中的一個地方,你可以添加一個鉤來切換類沒有完全照搬實施mapRow()爲BeanPropertyRowMapper。你最好的辦法可能是創建一個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; 

      } 
     } 
    }; 
+0

感謝您的回覆。這就是我最終做的!很好,以獲得一些驗證。 – jnt30 2009-12-03 14:28:13

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; 
}