com.alexkasko.springjdbc.parallel.CancellableStatementCreator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of parallel-queries Show documentation
Show all versions of parallel-queries Show documentation
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.
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();
}
}