All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alexkasko.springjdbc.parallel.CancellableStatementCreator Maven / Gradle / Ivy

Go to download

Processes given SQL query in parallel in multiple data sources (assuming that all data source contain the same data). Combined results from multiple queries are exposed to application as java.util.Iterator. Worker thread use spring's JdbcTemplate with named parameters support.

There is a newer version: 1.2.3
Show newest version
package com.alexkasko.springjdbc.parallel;

import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.namedparam.ParsedSql;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.Map;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue;
import static org.springframework.jdbc.core.namedparam.NamedParameterUtils.*;
import static org.springframework.util.StringUtils.hasText;

/**
 * {@code PreparedStatementCreator} implementation, that places created {@link PreparedStatement}
 * into provided registry for possible cancellation from other thread.
 * Other thread must check atomic reference payload for nullability.
 * Sql parameters processing is the same as in {@code NamedParameterJdbcTemplate}
 * Each instance should be used only once.
 *
 * @author alexkasko
 * Date: 11/6/12
 */
class CancellableStatementCreator implements PreparedStatementCreator {
    private final String registryKey;
    private final Map registry;
    private final String sql;
    private final SqlParameterSource params;

    /**
     * Main constructor
     *
     * @param registryKey registry key for created statement
     * @param registry statement registry
     * @param sql sql string with spring-jdbc named parameters
     * @param params parameter source
     */
    CancellableStatementCreator(String registryKey, Map registry, String sql, SqlParameterSource params) {
        checkArgument(hasText(registryKey), "Provided registry key is blank");
        checkNotNull(registry, "Provided registry is null");
        checkArgument(hasText(sql), "Provided sql is blank");
        checkNotNull(params, "Provided sql parameter source is null");
        this.registryKey = registryKey;
        this.registry = registry;
        this.sql = sql;
        this.params = params;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
        final PreparedStatement stmt;
        // substitute named params,
        // see NamedParameterJdbcTemplate#getPreparedStatementCreator(String sql, SqlParameterSource paramSource)
        ParsedSql parsedSql = parseSqlStatement(sql);
        String sqlToUse = substituteNamedParameters(parsedSql, params);
        stmt = con.prepareStatement(sqlToUse);
        Object[] parArray = buildValueArray(parsedSql, params, null);
        List parList = buildSqlParameterList(parsedSql, params);
        for(int i = 0; i < parArray.length; i++) {
            setParameterValue(stmt, i + 1, parList.get(i), parArray[i]);
        }
        registry.put(registryKey, stmt);
        return stmt;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        sb.append("CancellableStatementCreator");
        sb.append("{registryKey='").append(registryKey).append('\'');
        sb.append(", sql='").append(sql).append('\'');
        sb.append(", params=").append(params);
        sb.append('}');
        return sb.toString();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy