7

リーダーにアイテムのリストが表示されます。

Code各アイテムオブジェクトには、事前に知られていないいくつかの可能な値を持つプロパティが呼び出されます。

1)各項目の値に基づいて、Codeその特定の項目をそれに関連する出力ファイルに書き込みたいCode。たとえば、現在のアイテムCodeが「abc」の場合、そのアイテムはライターのabc.txtに書き込む必要があります。

2)Codeファイルが存在しない現在のアイテムに「xyz」がある場合、新しいファイルが作成され、アイテムはそのファイルに移動する必要があります。

3)に基づいて作成されたこのような複数のファイルすべてについてCode、ヘッダーとフッターのコールバックを追加して、各ファイルのアイテム数などの詳細を入力します。

上記の3つの要件を満たすライターを持つことは可能ですか?

multiresourceitemwriterを使用すると、データを複数の出力ファイルに分割できることを知っています。しかし、私が知る限り、この区分はアイテムの数に基づいています。たとえば、file1の最初の10個のアイテム、file2の次の10個など。

しかし、私の質問で述べたように、アイテムのプロパティに基づいてデータを出力ファイルにルーティングするにはどうすればよいですか?

私はSpringBatchに精通しており、この種の問題に直面するのはこれが初めてなので、少しのガイダンスが必要です。

読んでくれてありがとう!

4

6 に答える 6

9

私があなたの問題を正しく理解しているなら、あなたはいくつかのアイテムを必要とします。

まず、Classifierインターフェースを実装する分類子

public class ItemCodeClassifier {
    @Classifier
    public String classify(Item item) {
        return item.getCode().getKey();// returns "abc", "xyz"
    }
}

次に、上記の方法を使用するルーターの実装

<bean id="classifier"  class="org.springframework.batch.classify.BackToBackPatternClassifier">
    <property name="routerDelegate">
        <bean class="ItemCodeClassifier" />
    </property>
    <property name="matcherMap">
        <map>
        <entry key="abc" value-ref="abcItemWriter" />
        <entry key="xyz" value-ref="xyzItemWriter" />
        </map>
    </property>
</bean>

そして最後に、ClassifierCompositeItemWriter

<bean id="ItemWriter" class="org.springframework.batch.item.support.ClassifierCompositeItemWriter">
<property name="classifier" ref="classifier" />
</bean

上記をコンパイルしませんでしたが、それが役立つことを願っています。

于 2012-09-17T22:20:35.780 に答える
3

以下の解決策は私のために働いた。コードをコンパイルすると、正常に機能しています。

まず、分類子が必要になります。Classifierインターフェースを実装するか、@ Classifierでclassify()メソッドに注釈を付けます。

ここでは注釈を使用しました。

public class MyClassifier {
    @Classifier
    public String classify(Policy pol) {
        return pol.getPolCode;// returns "01", "02"
    }
}

分類器Beanを追加します

<bean id="myClassifier"  class="org.springframework.batch.classify.BackToBackPatternClassifier">
    <property name="routerDelegate">
        <bean class="MyClassifier" />
    </property>
    <property name="matcherMap">
        <map>
        <entry key="01" value-ref="pol01ItemWriter" />
        <entry key="02" value-ref="pol02ItemWriter" />
        </map>
    </property>
</bean>

以下のようにライターBeanを追加します

<bean id="ItemWriter" class="org.springframework.batch.item.support.ClassifierCompositeItemWriter">
    <property name="myClassifier" ref="myClassifier" />
</bean>

上記のコードはWriterNotOpenExceptionをスローする可能性があります。このためには、batch:streamをステップに追加する必要があります。

<batch:step id="step1">
    <batch:tasklet>
        <batch:chunk reader="reader" processor="processor" writer="ItemWriter" commit-interval="3">
            <batch:streams>
                <batch:stream ref="pol01ItemWriter"/>
                <batch:stream ref="pol02ItemWriter"/>
            </batch:streams>
        </batch:chunk>
    </batch:tasklet>
</batch:step>
于 2015-10-25T12:56:24.900 に答える
1

私は少なくとも2つの戦略でそれを試してみます

  1. バッチはすべてのデータを一時データベーステーブルに書き込み、単純なツール/バッチ/スクリプトが個々のファイルを作成します-ヘッダー/フッターについてはよくわかりませんが、いつものように「安くしましょう」と言うことができます
  2. itemWriterは、必要なライターをその場で作成および管理します。再起動のシナリオを無視する限り、「簡単」に聞こえる場合は、事前に構成された抽象的なライター/Beanをテンプレートとして使用できます。
于 2012-09-18T20:20:49.703 に答える
0

別のオプションは、コードで区切られた要素を含む3つのリストを作成することです。次に、別の手順を使用して、これらのリストをファイルシステムに書き込みます。

1つの利点は、要素を書き込む準備ができていることです。したがって、大きなバッファーを使用して、書き込みのスループットを向上させることができます(もちろんハードウェアに応じて)。

生成する必要のあるファイルの数が動的である場合は、マルチスレッドの問題を回避するために、それらを順番に書き込むことをお勧めします。

要素を動的にルーティングすることはできません。したがって、アイデアは、自分でルーティングされた要素のリストを作成してから、これらのリストで作業することです。

于 2012-09-17T14:20:53.747 に答える
0

JDBCライター用のJavaConfig

これは私がjdbcライターのためにそれをした方法です。フラットファイルライターについても同様の構成が可能です

 @Bean
    public ItemWriter<Person> itemWriter(DataSource dataSource) {
        BackToBackPatternClassifier classifier = new BackToBackPatternClassifier();
        classifier.setRouterDelegate(new AggGroupClassifier());
        classifier.setMatcherMap(new HashMap<String, ItemWriter<? extends Person>>() {
            {
                put("A", writerA(dataSource));
                put("B", writerB(dataSource));
                put("C", writerC(dataSource));

            }
        });
        ClassifierCompositeItemWriter<Person> writer = new ClassifierCompositeItemWriter<Person>();
        writer.setClassifier(classifier);
        return writer;      
        }


public class AggGroupClassifier {

    @Classifier
    public String classify(Person person) {
        return person.getAgeGroup();

    }
}
于 2018-12-05T06:49:56.820 に答える
-2

私は今朝、これと同じ問題に遭遇しました。そして最後に、Springバッチの最新リリース2.1.9バージョンでは、現在ClassifierCompositeItemWriterがFlatFileItemWriterをデリゲートItemWriterとしてサポートしていないことがわかりました。

WriterNotOpenExceptionは次のようにスローされます。

org.springframework.batch.item.WriterNotOpenException: Writer must be open before it can be written to
    at org.springframework.batch.item.file.FlatFileItemWriter.write(FlatFileItemWriter.java:236)
    at org.springframework.batch.item.support.ClassifierCompositeItemWriter.write(ClassifierCompositeItemWriter.java:65)
    at org.springframework.batch.core.step.item.SimpleChunkProcessor.writeItems(SimpleChunkProcessor.java:171)
    at org.springframework.batch.core.step.item.SimpleChunkProcessor.doWrite(SimpleChunkProcessor.java:150)
    at org.springframework.batch.core.step.item.SimpleChunkProcessor.write(SimpleChunkProcessor.java:269)
    at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:194)
    at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:74)
    at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:386)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
    at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:264)
    at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:76)
    at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:367)
    at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:214)
    at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:143)
    at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:250)
    at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:195)
    at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:135)
    at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:61)
    at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:60)
    at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:144)
    at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:124)
    at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135)
    at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:281)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:120)
    at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:48)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:114)
于 2013-03-31T09:32:36.330 に答える