java - Spring Batch 作业参数限制为 250 个字符?

标签 java oracle spring spring-batch

我正在使用 ItemReader/ItemWriter 设置 Spring Batch 作业将数据集从 Oracle DB 导出到 CSV/Excel/PDF。对于读者部分,我使用 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>

所以我将 SQL 语句添加到 JobParametersBuilder...

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 语句进入 STRING_VAL 列,该列限制为 250 个字符。我检查了其他数据库系统(MySQL 和 DB2)的 DDL,似乎到处都限制为 250 个字符。我现在将该列更改为 CLOB,工作正常并且我的作业运行。

我的问题:我简直不敢相信它的目的是通过批处理作业存储限制为 250 个字符的作业参数。那么对于我的场景是否有更好的实现,或者是否打算更改 BATCH_JOB_PARAMS 表中参数列的默认值?

最佳答案

不要将 SQL 作为作业的参数传递。相反,创建一个扩展 JdbcCursorItemReader 的类来实现 InitializingBean。

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>

preparedStatementSetter 示例:

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 子句中。

希望有帮助。

关于java - Spring Batch 作业参数限制为 250 个字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15905435/

相关文章:

java - 读取字符串直到出现整数

java - 如何从作为字符串给出的 java 代码中解析包?

SQL - 从 Select + 用户定义的列和值创建表

java - Spring 3.1 Web 应用程序问题

java - 使用 String bean 作为 SPEL 中的键从映射中获取值

java - XML 中定义的 boolean 值。如何在 Java 中引用?

sql - 为什么我的动态 to_char 不起作用?

asp.net - 如何将 'System.Drawing.Image' 添加到 'System.Web.UI.WebControls.Image'

java - 如何将 bean 注入(inject) @Controller 类

java - AJAX 响应不保留从服务器返回的 LinkedHashMap 的顺序