2017-08-08 15 views
1

私は、起動時に機能のトグル決定に基づいてMySQLまたはArangoDB(NoSqlデータベース)からデータを読み取り、いくつかのプロセスを実行し、再度MySQL/ArangoDBに書き戻す既存のバネ・バッチ・プロジェクトを持っています。別のDBのバッチ・バッチ・マルチプル・リーダー

さて、MySQLの読者構成が

@Bean 
@Primary 
@StepScope 
public HibernatePagingItemReader reader(
     @Value("#{jobParameters[oldMetadataDefinitionId]}") Long oldMetadataDefinitionId) { 

    Map<String, Object> queryParameters = new HashMap<>(); 
    queryParameters.put(Constants.OLD_METADATA_DEFINITION_ID, oldMetadataDefinitionId); 


    HibernatePagingItemReader<Long> reader = new HibernatePagingItemReader<>(); 

    reader.setUseStatelessSession(false); 
    reader.setPageSize(250); 
    reader.setParameterValues(queryParameters); 

    reader.setSessionFactory(((HibernateEntityManagerFactory) entityManagerFactory.getObject()).getSessionFactory()); 
    return reader; 
} 

、以下のようなものであり、私は以下のような別のアランゴリーダーを持って、

@Bean 
@StepScope 
public ListItemReader arangoReader(
     @Value("#{jobParameters[oldMetadataDefinitionId]}") Long oldMetadataDefinitionId) { 

    List<InstanceDTO> instanceList = new ArrayList<InstanceDTO>(); 

    PersistenceService arangoPersistence = arangoConfiguration 
      .getPersistenceService()); 

    List<Long> instanceIds = arangoPersistence.getDefinitionInstanceIds(oldMetadataDefinitionId); 

    instanceIds.forEach((instanceId) -> 
    { 
     InstanceDTO instanceDto = new InstanceDTO(); 
     instanceDto.setDefinitionID(oldMetadataDefinitionId); 
     instanceDto.setInstanceID(instanceId); 
     instanceList.add(instanceDto); 

    }); 

    return new ListItemReader(instanceList); 

} 

と私のステップの構成は以下の通りです

@Bean 
@SuppressWarnings("unchecked") 
public Step InstanceMergeStep(ListItemReader arangoReader, ItemWriter<MetadataInstanceDTO> arangoWriter, 
     ItemReader<Long> mysqlReader, ItemWriter<Long> mysqlWriter) { 

    Step step = null; 
    if (arangoUsage) { 
     step = steps.get("arangoInstanceMergeStep") 


       .<Long, Long>chunk(1) 

       .reader(arangoReader) 

       .writer(arangoWriter) 


       .faultTolerant() 


       .skip(Exception.class) 


       .skipLimit(10) 

       .taskExecutor(stepTaskExecutor()) 

       .build(); 


     ((TaskletStep) step).registerChunkListener(chunkListener); 
    } 
    else { 
     step = steps.get("mysqlInstanceMergeStep") 


       .<Long, Long>chunk(1) 

       .reader(mysqlReader) 

       .writer(mysqlWriter) 

       .faultTolerant() 

       .skip(Exception.class) 


       .skipLimit(failedSkipLimit) 

       .taskExecutor(stepTaskExecutor()) 

       .build(); 


     ((TaskletStep) step).registerChunkListener(chunkListener); 

    } 

    return step; 
} 

MySQLリーダーはHibernatePagingItemReaderを介してページネーションをサポートしているので、何百万ものアイテムがメモリの問題なしに。

私はarangoリーダーのための同じページネーションサポートを実装して、反復ごとにわずか250のドキュメントを取得したいのですが、どのようにこれを達成するためにarangoリーダーコードを変更できますか?

答えて

0

最初に書かれたListItemReaderのドキュメントには、 - と書かれていますので、のテストにお役立てください。実際の具体的なタイプではなく、すべてのリーダーBeanからItemReaderを返してください。

しかし、Spring Batch APIまたはSpring Dataは、Arango DBをサポートしていないようです。私が見つけることができる最も近いのはthis

です(以前はArango DBで作業していませんでした)。

だから私の意見では、あなたはおそらく抽象クラスを実装することにより、ページングを実装して独自のカスタムアランゴリーダーを記述する必要があります - org.springframework.batch.item.database.AbstractPagingItemReader

クラスの上に拡張することにより、そのがなんとかいない場合は、最初からすべてを実装する必要があります。 Spring Batch APIのすべてのページリーダーは、HibernatePagingItemReaderを含む抽象クラスを継承しています。また

、そのアランゴのレコードセットは、我々はページを区別することができるようにページネーションを実装するために注文のいくつかの種類を持っている必要があります覚えている - 0 &ページ-1など(ORDER BY句に似て、事業者などではより大きく、よりBETWEENオペレータ&少ないですSQL。FETCH FIRST XXX ROWS OR LIMIT句の種類も必要になります)。

可能なアイテムの合計を計算してから、ページに分割して一度に1ページしか取得しなければならないので、自分で実装することは非常に難しい作業ではありません。

アイデアを得るには、HibernatePagingItemReaderなどの実装についてはAPIをご覧ください。

希望すると助かります!

+0

上記の説明のための@sabirありがとうございました! Spring起動を使用してAQLクエリのレコードを制限するために、動的startIndexとendIndexを使用して複数回arangoMergeStepを呼び出すことは可能です。 – siva

+0

フレームワークによって繰り返し呼び出されるreaderの 'read()'メソッドです。その 'read()'メソッドは、ページが終了するまで一つ一つの項目を返し続け、次のページを取得しなければなりません。最後のページの最後の項目に 'null'を返します。'JdbcPagingItemReader'や' HibernatePagingItemReader'のような既存のクラスの1つを見てください。読み込みが呼び出されるたびに1つのアイテムを返すというのは、これらのアイテムとカウントを維持するカスタムリーダーの仕事です。 –

関連する問題