sql-server - spring batch:查询小任务中存储过程结果的有效方法
问题描述
我的目标是使用 spring 批处理 tasklet 中的自定义行映射器查询存储过程(sql server)的结果。
我正在使用 Spring Boot(版本 2.2.2.RELEASE)和 Spring Batch(4.2.1.RELEASE)。
例子:
存储过程:
CREATE PROCEDURE storedProcName @numbers VARCHAR(max), @day DATE
AS
SET NOCOUNT ON;
SELECT something, something2, something3
FROM sometable
WHERE ids in (select value from string_split(@numbers,','))
AND day = @day
自定义行映射器:
public class CustomRowMapper implements RowMapper<CustomObject> {
private static final String SOMETHING = "something";
private static final String SOMETHING2 = "something2";
private static final String SOMETHING3 = "something3";
@Override
public CustomObject mapRow(ResultSet resultSet, int i) throws SQLException {
CustomObject customObject = new CustomObject();
customObject.setSomething(resultSet.getString(SOMETHING));
customObject.setSomething2(resultSet.getString(SOMETHING2));
customObject.setSomething3(resultSet.getInt(SOMETHING3));
return customObject;
}
}
执行存储过程并查询结果:
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
.withProcedureName("storedProcName")
.returningResultSet("test", new CustomRowMapper());
Map<String, Object> out = jdbcCall.execute(parameterSource);
List<CustomObject> customObjects = (List<CustomObject>) out.get("test");
它工作正常,但必须有一种更有效的方法来做到这一点?但我没有发现任何有用的东西。
解决方案
必须有一种更有效的方法来做到这一点
Spring Batch 提供了StoredProcedureItemReader
可以调用给定存储过程并迭代其结果的方法。它还允许您使用自定义映射器作为您定义的映射器。
根据您的代码片段,您调用该过程并获得一个List<CustomObject>
您需要在某些时候迭代的过程。因此,我认为带有 a 的面向块的 taskletStoredProcedureItemReader<CustomObject>
对您来说是一个不错的选择:
@Bean
public StoredProcedureItemReader<CustomObject> itemReader() {
return new StoredProcedureItemReaderBuilder<CustomObject>()
.procedureName("storedProcName")
.rowMapper(new CustomRowMapper())
// set other properties
.build();
}
编辑:展示如何返回同步阅读器
@Bean
@StepScope
public SynchronizedItemStreamReader<CustomObject> itemReader() {
StoredProcedureItemReader<CustomObject> reader = new StoredProcedureItemReaderBuilder<>()
.procedureName("storedProcName")
.rowMapper(new CustomRowMapper())
// set other properties
.build();
SynchronizedItemStreamReader<CustomObject> synchronizedReader = new SynchronizedItemStreamReader<>();
synchronizedReader.setDelegate(reader);
return synchronizedReader;
}
推荐阅读
- laravel - laravel 为什么会话返回null?
- visual-studio-code - 在vscode中的对象检查中隐藏getter / setter?
- python - 使 gRPC 消息 JSON 可序列化
- sql - 使用 SQL 从贷方进行有条件借记
- javascript - 我无法弄清楚这个单一的脚本问题
- windows-services - 事件查看器中记录的 Microsoft 服务器打印机错误 (ID 1116)
- fipy - 我们可以通过坐标搜索找出一个点在FiPy中属于哪个网格吗?
- qt - QML 中的 HTML 弹出框
- sql-server - 为什么我无法从 SQL Server Management Studio 远程连接 SQL Server Report Server?
- php - SQLITE 创建具有唯一列的表