2009-12-02 6 views
5

SpringのJDBCを使用したクラス階層のマッピングに関してコミュニティが「ベストプラクティス」と考えるものを知りたかったのです。クラスHierediesを使用したSpring JDBC RowMapper

本格的なORMツールを使用する能力はありませんが、Springの退屈な性質を緩和するためにSpring JDBCを使用しています。 BeanPropertyRowMapperは、使いやすさと、結果セットからの型の影響を受けないBeanプロパティへのアクセスを可能にするクラスです。

私はすべてのマップを1つのテーブルにマップするクラス階層を持っています(この小さなクラス階層のテーブルごとのアプローチアプローチをとっています)。そのため、表には実際にインスタンス化するクラスを決定するために使用できるclassId列が含まれています。 Ex。 1 =マネージャ、2 =従業員、3 =請負業者。これらはすべて「人」ですが、個人の各サブクラスには、そのクラスに固有の属性がいくつかあります。

私の最初の考えは、BeanPropertyRowMapperのサブクラスを作成し、このロジックを挿入して "カラムA = 1の場合、マネージャをインスタンス化して名詞バインディングを実行する"と言うようにします。

これは合理的なアプローチのようですか?人々があなたのために働いたかもしれない他の提案はありますか?あなたの回答を事前に

おかげで、

ジャスティンN.

答えて

4

あなたは完全の実装をコピーせずにクラスを切り替えるようにフックを追加することができ、サブクラスで場所がありますようにそれが見えませんBeanPropertyRowMapperのmapRow()。最適な方法は、適切なBeanPropertyRowMapperに委譲するRowMapperクラスを作成することです。例えば

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

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; 
} 
関連する問題