将Spring Batch JdbcCursorItemReader与NamedParameters一起使用 [英] Using Spring Batch JdbcCursorItemReader with NamedParameters

查看:23
本文介绍了将Spring Batch JdbcCursorItemReader与NamedParameters一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Spring批处理JdbcCursorItemReader可以接受prepararedStatementSetter

<bean id="reader" class="org.springframework.batch.item.database.JdbcCursorItemReader">
   <property name="dataSource" ref="..." />
   <property name="sql" value="SELECT * FROM test WHERE col1 = ?">
   <property name="rowMapper" ref="..." />
   <property name="preparedStatementSetter" ref="..." />
</bean>

如果SQL使用作为占位符,则效果很好,如上例所示。但是,我们先前存在的SQL使用命名参数,例如SELECT*FROM TEST WHERE col1=:param

是否可以让JdbcCursorItemReader使用NamedPreparedStatementSetter而不是简单的PreparedStatementSetter?

谢谢

推荐答案

一旦我们没有来自Spring的官方解决方案,我们可以使用简单的方法解决此问题:

  1. 定义一个接口来提供SqlParameters:
import org.springframework.jdbc.core.namedparam.SqlParameterSource;

public interface SqlParameterSourceProvider { 
    SqlParameterSource getSqlParameterSource();
}
  1. 扩展JdbcCursorItemReader并添加namedParameter功能。
import org.springframework.batch.item.database.JdbcCursorItemReader;
import org.springframework.jdbc.core.SqlTypeValue;
import org.springframework.jdbc.core.StatementCreatorUtils;
import org.springframework.jdbc.core.namedparam.*;
import org.springframework.util.Assert;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.*;


public class NamedParameterJdbcCursorItemReader<T> extends JdbcCursorItemReader<T> {

    private SqlParameterSourceProvider parameterSourceProvider;
    private String paramedSql;

    public NamedParameterJdbcCursorItemReader(SqlParameterSourceProvider parameterSourceProvider) {
        this.parameterSourceProvider = parameterSourceProvider;
    }

    @Override
    public void setSql(String sql) {
        Assert.notNull(parameterSourceProvider, "You have to set parameterSourceProvider before the SQL statement");
        Assert.notNull(sql, "sql must not be null");
        paramedSql = sql;
        super.setSql(NamedParameterUtils.substituteNamedParameters(sql, parameterSourceProvider.getSqlParameterSource()));
    }

    @Override
    protected void applyStatementSettings(PreparedStatement stmt) throws SQLException {
        final ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(paramedSql);

        final List<?> parameters = Arrays.asList(NamedParameterUtils.buildValueArray(parsedSql, parameterSourceProvider.getSqlParameterSource(), null));
        for (int i = 0; i < parameters.size(); i++) {
            StatementCreatorUtils.setParameterValue(stmt, i + 1, SqlTypeValue.TYPE_UNKNOWN, parameters.get(i));
        }
    }
}
  1. 创建实现接口SqlParameterSourceProvider并具有要在查询中使用的参数的更新值的状态的具体类。
public class MyCustomSqlParameterSourceProvider implements SqlParameterSourceProvider {

    private Map<String, Object> params;

    public void updateParams(Map<String, Object> params) {
        this.params = params;
    }

    @Override
    public SqlParameterSource getSqlParameterSource() {
        final MapSqlParameterSource paramSource = new MapSqlParameterSource();
        paramSource.addValues(params);
        return paramSource;
    }
}
  1. 最后,更新弹簧配置。
<bean id="reader" class="org.wisecoding.stackoverflow.NamedParameterJdbcCursorItemReader">
    <constructor-arg ref="sqlParameterSourceProvider"/>        
    <property name="dataSource" ref="..." />
    <property name="sql" value=SELECT * FROM test WHERE col1 = :param" />
    <property name="rowMapper" ref="..." />
    <property name="preparedStatementSetter" ref="..." />
</bean>

<bean id="sqlParameterSourceProvider" class="org.wisecoding.stackoverflow.MyCustomSqlParameterSourceProvider">
</bean>

这篇关于将Spring Batch JdbcCursorItemReader与NamedParameters一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆