我正在使用 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/