私は次の簡単なタスクを達成しようとしています:
- ";" で区切られた SQL クエリを含むテキスト ファイルを読み取ります。
- 各クエリを個別のトランザクションで実行する
- 失敗した最初のクエリから実行を再開/再開できるようにします。
spring-batch でこれを実行しようとしました。(バージョン 2.1.8.RELEASE) 私が直面している問題は次のとおりです。
ItemReader
「;」までの数行を読み取る単純なすぐに使える構成を構成できませんでした。に渡す前にそれらを集約しますItemWriter
。
FieldSetMapper
単にフィールドがありません。私の入力は、SQL クエリを含むテキスト ファイルです。各クエリは 1 行以上を使用でき、クエリはセミコロンで区切られます。a を複雑な Bean に指定せずLineMapper
に a の内部を定義することは不可能のようです(マップするa を設定しようとしましたが、以下で説明する例外のために失敗しました)。ItemReader
FieldSetMapper
BeanWrapperFieldSetMapper
java.lang.String
質問 1:に渡す前にすべての行を 1 つの行に追加することだけが必要な場合、複雑なオブジェクトにセットをFieldSetMapper
使用して が必要なのはなぜですか? のプロパティを を参照するように構成すると、名前の数が値の数と等しくないという例外が発生します。spring-batch コードをデバッグしたところ、2 つの値が 1 つの名前にマッピングされていることがわかりました: name =%SOME_NAME% values ={%MY_SQL_QUERY%, ";"} で、行 123で例外がスローされます。prototypeBeanName
String
ItemWriter
fieldSetMapper
prototypeBeanName
java.lang.String
AbstractLineTokenizer.tokenize()
質問 2 : すぐに使用できる spring-batch を使用して回線集約を実現ItemReaders
できますか? はいの場合、どのように構成する必要がありますか? 構成に何か見落としがありますか? (下記参照)
構成:
<bean id="basicParamsIncrementer" class="com.linking.core.exec.control.BasicJobParamsIncrementer" />
<batch:job id="rwBatchJob" restartable="true" incrementer="basicParamsIncrementer">
<batch:step id="processBatchStep">
<batch:tasklet transaction-manager="transactionManager" >
<batch:chunk reader="batchFileItemReader" writer="sqlBatchFileWriter"
commit-interval="1" />
</batch:tasklet>
</batch:step>
</batch:job>
<bean id="batchFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resource"
value="classpath:/bat.sql.txt" />
<property name="recordSeparatorPolicy" ref="separatorPolicy" />
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer" ref="sqlTokenizer" />
<property name="fieldSetMapper" ref="sqlFieldSetMapper" />
</bean>
</property>
</bean>
<bean id="separatorPolicy" class="com.linking.core.SemiColonRecordSeparatorPolicy" />
<bean id="sqlTokenizer" class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="delimiter" value=";" />
<property name="names" value="sql,eol"/>
</bean>
<bean id="sqlFieldSetMapper" class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
<property name="prototypeBeanName" value="sql" />
</bean>
<bean id="sql" class="com.linking.core.model.SQL" scope="prototype" />
com.linking.core.model.SQL
タイプ の 2つのメンバーを持つ単純なクラスですString
: sql (クエリ用) およびeol
(';' 用)私の場合は ";") as .AbstractItemReader
String
values
質問 3:単一ステップのリーダー/ライター アプローチを使用して大量の SQL クエリを実行するジョブが途中で失敗した場合、最初に失敗したクエリからジョブを再開/再開するにはどうすればよいですか? 最後の実行を分析してプログラムで実行する必要がありますか、それともジョブステップと関連するすぐに使用できるSpring-Batch Beanのコンテキスト構成によって実現できますか?