package org.simpleflatmapper.jdbc.spring;
import org.simpleflatmapper.jdbc.JdbcMapper;
import org.simpleflatmapper.jdbc.named.NamedParameter;
import org.simpleflatmapper.jdbc.named.NamedSqlQuery;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterUtils;
import org.springframework.jdbc.core.namedparam.ParsedSql;
import org.springframework.jdbc.object.SqlQuery;
import javax.sql.DataSource;
import java.util.List;
import java.util.Map;
public class MappingSqlQuery<T> extends SqlQuery<T> {
private final PreparedStatementCallbackImpl<T> statementCallback;
public MappingSqlQuery(DataSource ds, String sql, JdbcMapper<T> mapper) {
super(ds, sql);
setParameters(extractParameters(sql));
statementCallback = new PreparedStatementCallbackImpl<T>(mapper);
afterPropertiesSet();
}
private SqlParameter[] extractParameters(String sql) {
NamedSqlQuery query = NamedSqlQuery.parse(sql);
SqlParameter[] params = new SqlParameter[query.getParametersSize()];
for(int i = 0; i < params.length; i++) {
NamedParameter namedParameter = query.getParameter(i);
params[i] = new SqlParameter(namedParameter.getName(), 0);
}
return params;
}
public List<T> execute(Object[] params, Map<?, ?> context) throws DataAccessException {
validateParameters(params);
return query(newPreparedStatementCreator(params));
}
public List<T> executeByNamedParam(Map<String, ?> paramMap, Map<?, ?> context) throws DataAccessException {
validateNamedParameters(paramMap);
ParsedSql parsedSql = getParsedSql();
MapSqlParameterSource paramSource = new MapSqlParameterSource(paramMap);
String sqlToUse = NamedParameterUtils.substituteNamedParameters(parsedSql, paramSource);
Object[] params = NamedParameterUtils.buildValueArray(parsedSql, paramSource, getDeclaredParameters());
return query(newPreparedStatementCreator(sqlToUse, params));
}
private List<T> query(PreparedStatementCreator preparedStatementCreator) {
return getJdbcTemplate().execute(preparedStatementCreator, statementCallback);
}
@Override
protected RowMapper<T> newRowMapper(Object[] parameters, Map<?, ?> context) {
throw new UnsupportedOperationException();
}
}