web-dev-qa-db-ja.com

ResultSetExtractorとRowmapperの違いは何ですか?

行マッパーと結果セット抽出のコールバックインターフェイスの両方で作業しました。違いが見つかりました。

1.行マッパーは行ごとに処理できますが、結果セット抽出ではすべての行をナビゲートでき、戻り値の型はオブジェクトです。

上記以外の違いはありますか?.

39
user1127214

ResultSetExtractorのJavaDoc

このインターフェイスは、主にJDBCフレームワーク自体で使用されます。通常、RowMapperはResultSet処理のためのより単純な選択であり、ResultSet全体に対して1つの結果オブジェクトではなく、行ごとに1つの結果オブジェクトをマッピングします。

ResultSetExtractorResultSet(おそらく複数の行)全体を抽出すると仮定しますが、 RowMapper は時間。

ほとんどの場合、ResultSetExtractorResultSetをループし、Spring RowMapperのスニペットの例であるRowMapperResultSetExtractorを使用します。

List<T> results = (this.rowsExpected > 0 ? new ArrayList<T>(this.rowsExpected) : new ArrayList<T>());
int rowNum = 0;
while (rs.next()) {
    results.add(this.rowMapper.mapRow(rs, rowNum++));
}
return results;

注意してください、すべての結果が変換され、これによりメモリ不足例外が発生する可能性があります。

こちらもご覧ください

26

基本的な違いは、ResultsetExtractorでは、whileループで結果セットを繰り返し処理する必要があることです。このインターフェイスを使用すると、ResultSet全体を一度に処理できます。インターフェイスメソッドextractData(ResultSet rs)の実装には、その手動の反復コードが含まれます。 ResultsetExtractorの実装の1つを参照

rowCallbackHandlerのようなコールバックハンドラーの中には、インターフェイスメソッドprocessRow(ResultSet rs)がループします。

RowMapperは、各行または行全体のマッピングに使用できます。

行オブジェクト全体(テンプレートメソッドjdbcTemplate.query()による)

 public List findAll() {    
    String sql = "SELECT * FROM EMPLOYEE";
    return jdbcTemplate.query(sql, new EmployeeRowMapper());
} 
without casting will work

個々のオブジェクトの場合(テンプレートメソッドjdbcTemplate.queryForObject()を使用)

@SuppressWarnings({ "unchecked", "rawtypes" })
public Employee findById(int id) {
    String sql = "SELECT * FROM EMPLOYEE WHERE ID = ?";
//  jdbcTemplate = new JdbcTemplate(dataSource);

    Employee employee = (Employee) jdbcTemplate.queryForObject(sql,  new EmployeeRowMapper(), id );

    // Method 2 very easy
    //  Employee employee = (Employee) jdbcTemplate.queryForObject(sql, new Object[] { id }, new BeanPropertyRowMapper(Employee.class));

    return employee;
}

@SuppressWarnings("rawtypes")
public class EmployeeRowMapper implements RowMapper {

public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
    Employee employee = new Employee();
    employee.setId(rs.getInt("ID"));
    employee.setName(rs.getString("NAME"));
    employee.setAge(rs.getInt("AGE"));
    return employee;
}

}

最適な使用例:

行マッパー:ResultSetの各行がドメインオブジェクトにマップされる場合、プライベート内部クラスとして実装できます。

RowCallbackHandler:各行のコールバックメソッドから値が返されない場合、たとえば行をファイルに書き込み、行をXMLに変換し、コレクションに追加する前に行をフィルタリングします。 ResultSetからオブジェクトへのマッピングはここでは行われないため、非常に効率的です。

ResultSetExtractor:ResultSetの複数の行が単一のオブジェクトにマッピングされる場合。クエリで複雑な結合を行うときのように、複雑なオブジェクトを作成するには、rsの単一行ではなくResultSet全体にアクセスする必要があり、ResultSetを完全に制御したい場合があります。同様に、TABLE1とTABLE2の結合から返された行を完全に再構成されたTABLE集計にマッピングします。

ParameterizedRowMapperは、複雑なオブジェクトの作成に使用されます

39
vimal krishna

RowMapper:ResultSetの1レコードを一度に処理します。

ResultSetExtractor:ResultSetの複数のレコードを一度に処理します。

ResultSetExtractorが有利になる可能性があるのは、結果セット(ストアドプロシージャの呼び出しなど)と行マッパーがあり、jdbcTemplateメソッドのカバーの下で行われるように処理したい場合です。 query(String sql、RowMapper rowMapper)。この場合、RowMapperだけでなくResultSetExtractorを使用して、結果セットを手動で繰り返す必要がなくなります。

例えば:

RowMapper

ResultSet resultSet = cs.executeQuery();
int row = 0;
DateRowMapper dateRowMapper = new DateRowMapper();
List<String> dates = new ArrayList<>();
while (resultSet.next()) {
    dates.add(dateRowMapper.mapRow(resultSet, ++row));
}
return dates;

ResultSetExtractor

ResultSet resultSet = callableStatement.executeQuery();
return new RowMapperResultSetExtractor<>(new DateRowMapper()).extractData(resultSet);
0
MMW