行マッパーと結果セット抽出のコールバックインターフェイスの両方で作業しました。違いが見つかりました。
1.行マッパーは行ごとに処理できますが、結果セット抽出ではすべての行をナビゲートでき、戻り値の型はオブジェクトです。
上記以外の違いはありますか?.
このインターフェイスは、主にJDBCフレームワーク自体で使用されます。通常、RowMapperはResultSet処理のためのより単純な選択であり、ResultSet全体に対して1つの結果オブジェクトではなく、行ごとに1つの結果オブジェクトをマッピングします。
ResultSetExtractor
はResultSet
(おそらく複数の行)全体を抽出すると仮定しますが、 RowMapper
は時間。
ほとんどの場合、ResultSetExtractor
はResultSet
をループし、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;
注意してください、すべての結果が変換され、これによりメモリ不足例外が発生する可能性があります。
基本的な違いは、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は、複雑なオブジェクトの作成に使用されます
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);