1

Oracle DB から CSV/Excel/PDF にデータセットをエクスポートするために、 ItemReader/ItemWriterを使用して Spring Batch Job を設定しています。リーダー部分については、JdbcCursorItemReaderを使用しています。

デフォルトでは、SQL ステートメントをリーダーに渡してデータセットを抽出する必要があります。これが私のリーダー構成です。

<bean id="readErgebnis" class="org.springframework.batch.item.database.JdbcCursorItemReader" scope="step">
    <property name="dataSource" ref="dataSource" />
    <property name="sql" value="#{jobParameters['stmt']}" />
    <property name="rowMapper">
        <bean class="myFancyRowMapper" />
    </property>
</bean>

そこで、JobParametersBuilder に SQL ステートメントを追加しました...

JobParametersBuilder builder = new JobParametersBuilder(); 
builder.addString("stmt", sql);

それでいいはずです。ただし、ジョブの実行はSQLException.

これで、Spring Batch がすべてをログ テーブルに記録していることがわかりました。問題があります。パラメーター文字列 (SQL を含む) は 250 文字に制限されています。BATCH_JOB_PARAMS テーブルの定義を参照してください。

CREATE TABLE BATCH_JOB_PARAMS  (
    JOB_INSTANCE_ID NUMBER(19,0) NOT NULL ,
    TYPE_CD VARCHAR2(6) NOT NULL ,
    KEY_NAME VARCHAR2(100) NOT NULL , 
    STRING_VAL VARCHAR2(250), 
    DATE_VAL TIMESTAMP DEFAULT NULL ,
    LONG_VAL NUMBER(19,0) ,
    DOUBLE_VAL NUMBER ,
    constraint JOB_INST_PARAMS_FK foreign key (JOB_INSTANCE_ID)
    references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID)
);

Spring Batch はすべてのジョブ パラメーターを新しい行に格納するため、SQL ステートメントは 250 文字に制限されている STRING_VAL 列に入ります。他のデータベース システム (MySQL および DB2) の DDL を確認したところ、どこでも 250 文字に制限されているようです。その列をCLOB今に変更し、正常に動作し、ジョブが実行されます。

私の質問: バッチ ジョブを介して 250 文字に制限されたジョブ パラメーターを保存することを意図しているとは信じられません。私のシナリオに適した実装はありますか、それとも BATCH_JOB_PARAMS テーブルのパラメーター列のデフォルト値を変更することを意図していますか?

4

1 に答える 1

3

ジョブのパラメーターとして SQL を渡さないでください。代わりに、InitializingBean を実装する JdbcCursorItemReader を拡張するクラスを作成します。

package xxx.readers;

public class MyReader  extends  JdbcCursorItemReader<AnObjet> implements InitializingBean{


@Override
public void afterPropertiesSet() throws Exception {
        // set the SQL

    String SELECT_PAYMENT = "SELECT * from table"
    super.setSql(SELECT_PAYMENT);

    }
}

このようにして、起動時にSpringコンテキストによってBeanが初期化されるときにSQLが設定されます。

where 句を追加する必要がある場合は、PreparedStatementSetter を使用して構成に追加します。

    <bean id="myReader" class="xxx.readers.MyReader">
    <property name="dataSource" ref="aDataSource" />
    <property name="rowMapper" ref="aMapper" />     
    <property name="preparedStatementSetter" ref="yourPreparedStatementSetter" />
</bean>

準備されたStatementSetterの例:

package fcdq.iemt.batch.concilliation.utils;

import java.sql.PreparedStatement;
 import java.sql.SQLException;

 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jdbc.core.PreparedStatementSetter;
 import org.springframework.stereotype.Component;



 @Component("aPrStatSetter")
 public class RunNoSetter implements PreparedStatementSetter {


public void setValues(PreparedStatement ps) throws SQLException {
    ps.setString(1, "hello");
    ps.setString(2, "Hola");
    ps.setTimestamp(3, aTimestamp);
}
 }

実行時に PreparedStatementSetter が呼び出され、? where句で。

それが役立つことを願っています。

于 2013-04-09T15:11:29.427 に答える