[阅读: 635] 2006-11-21 09:13:47
package org.springframework.jdbc.core;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import javax.sql.DataSource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.SQLWarningException;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.support.JdbcAccessor;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;
import org.springframework.util.Assert;
public class MyJdbcTemplate extends JdbcAccessor {
private NativeJdbcExtractor nativeJdbcExtractor;
/**
* If this variable is set to a non-zero value, it will be used for setting
* the fetchSize property on statements used for query processing.
*/
private int fetchSize = 0;
/**
* If this variable is set to a non-zero value, it will be used for setting
* the maxRows property on statements used for query processing.
*/
private int maxRows = 0;
private boolean ignoreWarnings = true;
public void setNativeJdbcExtractor(NativeJdbcExtractor extractor) {
this.nativeJdbcExtractor = extractor;
}
/**
* Return the current NativeJdbcExtractor implementation.
*/
public NativeJdbcExtractor getNativeJdbcExtractor() {
return this.nativeJdbcExtractor;
}
PreparedStatementCallback preparedStatementCallback = new PreparedStatementCallback() {
public Object doInPreparedStatement(PreparedStatement ps)
throws SQLException {
try {
int rows = ps.executeUpdate();
if (logger.isDebugEnabled()) {
logger.debug("SQL update affected " + rows + " rows");
}
return new Integer(rows);
} finally {
}
}
};
public MyJdbcTemplate() {
}
public MyJdbcTemplate(DataSource dataSource) {
setDataSource(dataSource);
afterPropertiesSet();
}
public int update(PreparedStatementCreator psc) throws DataAccessException {
return update(psc, (PreparedStatementSetter) null);
}
protected int update(final PreparedStatementCreator psc,
final PreparedStatementSetter pss) throws DataAccessException {
if (logger.isDebugEnabled()) {
String sql = getSql(psc);
logger.debug("Executing SQL update"
+ (sql != null ? " [" + sql + "]" : ""));
}
System.out.println("update method invoke\n");
Integer result = (Integer) execute(psc, preparedStatementCallback);
return result.intValue();
}
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");
System.out.println("execute method invoke\n");
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);
SQLWarning warning = ps.getWarnings();
throwExceptionOnWarningIfNotIgnoringWarnings(warning);
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());
}
}
protected void applyStatementSettings(Statement stmt) throws SQLException {
if (getFetchSize() > 0) {
stmt.setFetchSize(getFetchSize());
}
if (getMaxRows() > 0) {
stmt.setMaxRows(getMaxRows());
}
DataSourceUtils.applyTransactionTimeout(stmt, getDataSource());
}
public void setFetchSize(int fetchSize) {
this.fetchSize = fetchSize;
}
/**
* Return the fetch size specified for this JdbcTemplate.
*/
public int getFetchSize() {
return fetchSize;
}
/**
* Set the maximum number of rows for this JdbcTemplate. This is important
* for processing subsets of large result sets, avoiding to read and hold
* the entire result set in the database or in the JDBC driver if we're
* never interested in the entire result in the first place (for example,
* when performing searches that might return a large number of matches).
* <p>
* Default is 0, indicating to use the JDBC driver's default.
*/
public void setMaxRows(int maxRows) {
this.maxRows = maxRows;
}
/**
* Return the maximum number of rows specified for this JdbcTemplate.
*/
public int getMaxRows() {
return maxRows;
}
public void setIgnoreWarnings(boolean ignoreWarnings) {
this.ignoreWarnings = ignoreWarnings;
}
/**
* Return whether or not we ignore SQLWarnings. Default is "true".
*/
public boolean isIgnoreWarnings() {
return ignoreWarnings;
}
/**
* Determine SQL from potential provider object.
*
* @param sqlProvider
* object that's potentially a SqlProvider
* @return the SQL string, or <code>null</code>
* @see SqlProvider
*/
private static String getSql(Object sqlProvider) {
if (sqlProvider instanceof SqlProvider) {
return ((SqlProvider) sqlProvider).getSql();
} else {
return null;
}
}
private void throwExceptionOnWarningIfNotIgnoringWarnings(SQLWarning warning)
throws SQLWarningException {
if (warning != null) {
if (isIgnoreWarnings()) {
if (logger.isWarnEnabled()) {
logger.warn("SQLWarning ignored: SQL state '"
+ warning.getSQLState() + "', error code '"
+ warning.getErrorCode() + "', message ["
+ warning.getMessage() + "]");
}
} else {
throw new SQLWarningException("Warning not ignored", warning);
}
}
}
}
MyJdbcTemplate类中有这个的一个方法:
public Object execute(PreparedStatementCreator psc,
PreparedStatementCallback action) throws DataAccessException
这里,偶对action跟踪的时候,发现是这样的.偶就不明白了.
这里的action应该为PreparedStatementCallback,这是一个回调接口,可是它却是
MyJdbcTemplate,不解?还有这个回调接口的搞法,偶迷糊了.