jdbctemplate.java
来自「spring framework 2.5.4源代码」· Java 代码 · 共 1,366 行 · 第 1/4 页
JAVA
1,366 行
}
catch (SQLException ex) {
// Release Connection early, to avoid potential connection pool deadlock
// in the case when the exception translator hasn't been initialized yet.
DataSourceUtils.releaseConnection(con, getDataSource());
con = null;
throw getExceptionTranslator().translate("ConnectionCallback", getSql(action), ex);
}
finally {
DataSourceUtils.releaseConnection(con, getDataSource());
}
}
/**
* Create a close-suppressing proxy for the given JDBC Connection.
* Called by the <code>execute</code> method.
* <p>The proxy also prepares returned JDBC Statements, applying
* statement settings such as fetch size, max rows, and query timeout.
* @param con the JDBC Connection to create a proxy for
* @return the Connection proxy
* @see java.sql.Connection#close()
* @see #execute(ConnectionCallback)
* @see #applyStatementSettings
*/
protected Connection createConnectionProxy(Connection con) {
return (Connection) Proxy.newProxyInstance(
ConnectionProxy.class.getClassLoader(),
new Class[] {ConnectionProxy.class},
new CloseSuppressingInvocationHandler(con));
}
//-------------------------------------------------------------------------
// Methods dealing with static SQL (java.sql.Statement)
//-------------------------------------------------------------------------
public Object execute(StatementCallback action) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
Connection con = DataSourceUtils.getConnection(getDataSource());
Statement stmt = null;
try {
Connection conToUse = con;
if (this.nativeJdbcExtractor != null &&
this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()) {
conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
}
stmt = conToUse.createStatement();
applyStatementSettings(stmt);
Statement stmtToUse = stmt;
if (this.nativeJdbcExtractor != null) {
stmtToUse = this.nativeJdbcExtractor.getNativeStatement(stmt);
}
Object result = action.doInStatement(stmtToUse);
handleWarnings(stmt.getWarnings());
return result;
}
catch (SQLException ex) {
// Release Connection early, to avoid potential connection pool deadlock
// in the case when the exception translator hasn't been initialized yet.
JdbcUtils.closeStatement(stmt);
stmt = null;
DataSourceUtils.releaseConnection(con, getDataSource());
con = null;
throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex);
}
finally {
JdbcUtils.closeStatement(stmt);
DataSourceUtils.releaseConnection(con, getDataSource());
}
}
public void execute(final String sql) throws DataAccessException {
if (logger.isDebugEnabled()) {
logger.debug("Executing SQL statement [" + sql + "]");
}
class ExecuteStatementCallback implements StatementCallback, SqlProvider {
public Object doInStatement(Statement stmt) throws SQLException {
stmt.execute(sql);
return null;
}
public String getSql() {
return sql;
}
}
execute(new ExecuteStatementCallback());
}
public Object query(final String sql, final ResultSetExtractor rse) throws DataAccessException {
Assert.notNull(sql, "SQL must not be null");
Assert.notNull(rse, "ResultSetExtractor must not be null");
if (logger.isDebugEnabled()) {
logger.debug("Executing SQL query [" + sql + "]");
}
class QueryStatementCallback implements StatementCallback, SqlProvider {
public Object doInStatement(Statement stmt) throws SQLException {
ResultSet rs = null;
try {
rs = stmt.executeQuery(sql);
ResultSet rsToUse = rs;
if (nativeJdbcExtractor != null) {
rsToUse = nativeJdbcExtractor.getNativeResultSet(rs);
}
return rse.extractData(rsToUse);
}
finally {
JdbcUtils.closeResultSet(rs);
}
}
public String getSql() {
return sql;
}
}
return execute(new QueryStatementCallback());
}
public void query(String sql, RowCallbackHandler rch) throws DataAccessException {
query(sql, new RowCallbackHandlerResultSetExtractor(rch));
}
public List query(String sql, RowMapper rowMapper) throws DataAccessException {
return (List) query(sql, new RowMapperResultSetExtractor(rowMapper));
}
public Map queryForMap(String sql) throws DataAccessException {
return (Map) queryForObject(sql, getColumnMapRowMapper());
}
public Object queryForObject(String sql, RowMapper rowMapper) throws DataAccessException {
List results = query(sql, rowMapper);
return DataAccessUtils.requiredSingleResult(results);
}
public Object queryForObject(String sql, Class requiredType) throws DataAccessException {
return queryForObject(sql, getSingleColumnRowMapper(requiredType));
}
public long queryForLong(String sql) throws DataAccessException {
Number number = (Number) queryForObject(sql, Long.class);
return (number != null ? number.longValue() : 0);
}
public int queryForInt(String sql) throws DataAccessException {
Number number = (Number) queryForObject(sql, Integer.class);
return (number != null ? number.intValue() : 0);
}
public List queryForList(String sql, Class elementType) throws DataAccessException {
return query(sql, getSingleColumnRowMapper(elementType));
}
public List queryForList(String sql) throws DataAccessException {
return query(sql, getColumnMapRowMapper());
}
public SqlRowSet queryForRowSet(String sql) throws DataAccessException {
return (SqlRowSet) query(sql, new SqlRowSetResultSetExtractor());
}
public int update(final String sql) throws DataAccessException {
Assert.notNull(sql, "SQL must not be null");
if (logger.isDebugEnabled()) {
logger.debug("Executing SQL update [" + sql + "]");
}
class UpdateStatementCallback implements StatementCallback, SqlProvider {
public Object doInStatement(Statement stmt) throws SQLException {
int rows = stmt.executeUpdate(sql);
if (logger.isDebugEnabled()) {
logger.debug("SQL update affected " + rows + " rows");
}
return new Integer(rows);
}
public String getSql() {
return sql;
}
}
return ((Integer) execute(new UpdateStatementCallback())).intValue();
}
public int[] batchUpdate(final String[] sql) throws DataAccessException {
Assert.notEmpty(sql, "SQL array must not be empty");
if (logger.isDebugEnabled()) {
logger.debug("Executing SQL batch update of " + sql.length + " statements");
}
class BatchUpdateStatementCallback implements StatementCallback, SqlProvider {
private String currSql;
public Object doInStatement(Statement stmt) throws SQLException, DataAccessException {
int[] rowsAffected = new int[sql.length];
if (JdbcUtils.supportsBatchUpdates(stmt.getConnection())) {
for (int i = 0; i < sql.length; i++) {
this.currSql = sql[i];
stmt.addBatch(sql[i]);
}
rowsAffected = stmt.executeBatch();
}
else {
for (int i = 0; i < sql.length; i++) {
this.currSql = sql[i];
if (!stmt.execute(sql[i])) {
rowsAffected[i] = stmt.getUpdateCount();
}
else {
throw new InvalidDataAccessApiUsageException("Invalid batch SQL statement: " + sql[i]);
}
}
}
return rowsAffected;
}
public String getSql() {
return currSql;
}
}
return (int[]) execute(new BatchUpdateStatementCallback());
}
//-------------------------------------------------------------------------
// Methods dealing with prepared statements
//-------------------------------------------------------------------------
public Object execute(PreparedStatementCreator psc, PreparedStatementCallback action)
throws DataAccessException {
Assert.notNull(psc, "PreparedStatementCreator must not be null");
Assert.notNull(action, "Callback object must not be null");
if (logger.isDebugEnabled()) {
String sql = getSql(psc);
logger.debug("Executing prepared SQL statement" + (sql != null ? " [" + sql + "]" : ""));
}
Connection con = DataSourceUtils.getConnection(getDataSource());
PreparedStatement ps = null;
try {
Connection conToUse = con;
if (this.nativeJdbcExtractor != null &&
this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativePreparedStatements()) {
conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
}
ps = psc.createPreparedStatement(conToUse);
applyStatementSettings(ps);
PreparedStatement psToUse = ps;
if (this.nativeJdbcExtractor != null) {
psToUse = this.nativeJdbcExtractor.getNativePreparedStatement(ps);
}
Object result = action.doInPreparedStatement(psToUse);
handleWarnings(ps.getWarnings());
return result;
}
catch (SQLException ex) {
// Release Connection early, to avoid potential connection pool deadlock
// in the case when the exception translator hasn't been initialized yet.
if (psc instanceof ParameterDisposer) {
((ParameterDisposer) psc).cleanupParameters();
}
String sql = getSql(psc);
psc = null;
JdbcUtils.closeStatement(ps);
ps = null;
DataSourceUtils.releaseConnection(con, getDataSource());
con = null;
throw getExceptionTranslator().translate("PreparedStatementCallback", sql, ex);
}
finally {
if (psc instanceof ParameterDisposer) {
((ParameterDisposer) psc).cleanupParameters();
}
JdbcUtils.closeStatement(ps);
DataSourceUtils.releaseConnection(con, getDataSource());
}
}
public Object execute(String sql, PreparedStatementCallback action) throws DataAccessException {
return execute(new SimplePreparedStatementCreator(sql), action);
}
/**
* Query using a prepared statement, allowing for a PreparedStatementCreator
* and a PreparedStatementSetter. Most other query methods use this method,
* but application code will always work with either a creator or a setter.
* @param psc Callback handler that can create a PreparedStatement given a
* Connection
* @param pss object that knows how to set values on the prepared statement.
* If this is null, the SQL will be assumed to contain no bind parameters.
* @param rse object that will extract results.
* @return an arbitrary result object, as returned by the ResultSetExtractor
* @throws DataAccessException if there is any problem
*/
public Object query(
PreparedStatementCreator psc, final PreparedStatementSetter pss, final ResultSetExtractor rse)
throws DataAccessException {
Assert.notNull(rse, "ResultSetExtractor must not be null");
logger.debug("Executing prepared SQL query");
return execute(psc, new PreparedStatementCallback() {
public Object doInPreparedStatement(PreparedStatement ps) throws SQLException {
ResultSet rs = null;
try {
if (pss != null) {
pss.setValues(ps);
}
rs = ps.executeQuery();
ResultSet rsToUse = rs;
if (nativeJdbcExtractor != null) {
rsToUse = nativeJdbcExtractor.getNativeResultSet(rs);
}
return rse.extractData(rsToUse);
}
finally {
JdbcUtils.closeResultSet(rs);
if (pss instanceof ParameterDisposer) {
((ParameterDisposer) pss).cleanupParameters();
}
}
}
});
}
public Object query(PreparedStatementCreator psc, ResultSetExtractor rse) throws DataAccessException {
return query(psc, null, rse);
}
public Object query(String sql, PreparedStatementSetter pss, ResultSetExtractor rse) throws DataAccessException {
return query(new SimplePreparedStatementCreator(sql), pss, rse);
}
public Object query(String sql, Object[] args, int[] argTypes, ResultSetExtractor rse) throws DataAccessException {
return query(sql, new ArgTypePreparedStatementSetter(args, argTypes), rse);
}
public Object query(String sql, Object[] args, ResultSetExtractor rse) throws DataAccessException {
return query(sql, new ArgPreparedStatementSetter(args), rse);
}
public void query(PreparedStatementCreator psc, RowCallbackHandler rch) throws DataAccessException {
query(psc, new RowCallbackHandlerResultSetExtractor(rch));
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?