4.1.4.5.1. データベースを入力とするChunkステップ

データベースから処理対象データを抽出する場合は、JSR352で提供されているリーダではなく 本機能で提供する BaseDatabaseItemReader を実装すること。

BaseDatabaseItemReader を実装することで、 リーダ専用のデータベース接続を使用してデータを抽出できる。 これにより、トランザクション制御時にカーソルを自動的にクローズするデータベースの場合でも、 データベースを入力とするChunkステップを実現できる。

以下に実装例を示す。

@Dependent
@Named
public class EmployeeSearchReader extends BaseDatabaseItemReader {

  /** データベースからの取得結果(リソース解放用) */
  private DeferredEntityList<EmployeeForm> list;

  /** データベースからの取得結果を保持するイテレータ */
  private Iterator<EmployeeForm> iterator;

  /** 進捗管理Bean */
  private final ProgressManager progressManager;

  /**
   * コンストラクタ。
   * @param progressManager 進捗管理Bean
   */
  @Inject
  public EmployeeSearchReader(ProgressManager progressManager) {
    this.progressManager = progressManager;
  }

  /**
   * BaseDatabaseItemReaderが提供するdoOpenを実装して、データベースから処理対象データを抽出する。
   * 大量データを取得する場合には、ヒープを圧迫しないよう遅延ロードを行うこと
   */
  @Override
  public void doOpen(Serializable checkpoint) throws Exception {
    progressManager.setInputCount(
        UniversalDao.countBySqlFile(EmployeeForm.class, "SELECT_EMPLOYEE"));

    list = (DeferredEntityList<EmployeeForm>) UniversalDao.defer()
            .findAllBySqlFile(EmployeeForm.class, "SELECT_EMPLOYEE");
    iterator = list.iterator();
  }

  /**
   * readItemでは、次の1レコードを返す。
   * なお、データが存在しない場合や最後まで処理した場合はnullを返す。
   */
  @Override
  public Object readItem() {
      if (iterator.hasNext()) {
          return iterator.next();
      }
      return null;
  }

  /**
   * リソースの解放が必要な場合は、doCloseを実装する。
   */
  @Override
  public void doClose() throws Exception {
      list.close();
  }
}