package com.skyline.energy.provider.spring;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.ColumnMapRowMapper;
import org.springframework.jdbc.core.InterruptibleBatchPreparedStatementSetter;
import org.springframework.jdbc.core.ParameterDisposer;
import org.springframework.jdbc.core.PreparedStatementCallback;
import org.springframework.jdbc.core.RowMapperResultSetExtractor;
import org.springframework.jdbc.support.JdbcUtils;
import com.skyline.energy.dataaccess.jdbc.KeyHolder;
public final class PreparedStatementCallbackCreator {
private PreparedStatementCallbackCreator() {
}
public static PreparedStatementCallback<int[]> createPreparedStatementCallback(
final BatchPreparedStatementSetter pss, final KeyHolder generatedKeyHolder) {
PreparedStatementCallback<int[]> callback = new PreparedStatementCallback<int[]>() {
@Override
public int[] doInPreparedStatement(PreparedStatement ps) throws SQLException {
try {
int batchSize = pss.getBatchSize();
InterruptibleBatchPreparedStatementSetter ipss = null;
if (pss instanceof InterruptibleBatchPreparedStatementSetter) {
ipss = (InterruptibleBatchPreparedStatementSetter) pss;
}
if (JdbcUtils.supportsBatchUpdates(ps.getConnection())) {
for (int i = 0; i < batchSize; i++) {
pss.setValues(ps, i);
if (ipss != null && ipss.isBatchExhausted(i)) {
break;
}
ps.addBatch();
}
int[] rows = ps.executeBatch();
return processResult(ps, rows, true);
} else {
List<Integer> rowsAffected = new ArrayList<Integer>();
int[] rows = new int[1];
for (int i = 0; i < batchSize; i++) {
pss.setValues(ps, i);
if (ipss != null && ipss.isBatchExhausted(i)) {
break;
}
int rowAffected = ps.executeUpdate();
rows[0] = rowAffected;
rowsAffected.add(rowAffected);
processResult(ps, rows, (i == 0)); // 第一次清空KeyHolder
}
return processAffectedArray(rowsAffected);
}
} finally {
if (pss instanceof ParameterDisposer) {
((ParameterDisposer) pss).cleanupParameters();
}
}
}
private int[] processAffectedArray(List<Integer> rowsAffected) {
int[] rowsAffectedArray = new int[rowsAffected.size()];
for (int i = 0; i < rowsAffectedArray.length; i++) {
rowsAffectedArray[i] = rowsAffected.get(i);
}
return rowsAffectedArray;
}
private int[] processResult(PreparedStatement ps, int[] rows, boolean clearKeys) throws SQLException {
if (generatedKeyHolder != null) {
List<Map<String, Object>> generatedKeys = generatedKeyHolder.getKeyList();
if (clearKeys) {
generatedKeys.clear();
}
ResultSet keys = ps.getGeneratedKeys();
if (keys != null) {
try {
RowMapperResultSetExtractor<Map<String, Object>> rse =
new RowMapperResultSetExtractor<Map<String, Object>>(
new ColumnMapRowMapper(), rows.length);
generatedKeys.addAll(rse.extractData(keys));
} finally {
JdbcUtils.closeResultSet(keys);
}
}
}
return rows;
}
};
return callback;
}
}