程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 模板模式在Spring 中的應用

模板模式在Spring 中的應用

編輯:關於JAVA

在spring裡面我們一般是這樣來使用模板模式的:

JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.update("UPDATE user SET age = 10 WHERE id = 'erica'");

或者:

JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate
.update(
"UPDATE user SET age = ? WHERE id = ?",
new PreparedStatementSetter() {
public void setValues(PreparedStatementSetter ps)
throws SQLException {
ps.setInt(1, 18);
ps.setString(2, "erica");
}
}
);

那麼具體在spring裡面他是怎麼運作的呢?

下面以query查詢為例:

public class JdbcTemplate extends JdbcAccessor implements JdbcOperations, InitializingBean {
。。。。。。。。。。。。。。。。。。。。。。。。。
protected Object query(
PreparedStatementCreator psc, final PreparedStatementSetter pss, final ResultSetExtractor rse)
throws DataAccessException {
if (logger.isDebugEnabled()) {
String sql = getSql(psc);
logger.debug("Executing SQL query" + (sql != null ? " [" + sql + "]" : ""));
}
return execute(psc, new PreparedStatementCallback() {
//此處以 PreparedStatementCallback 為參數調用 execute()方法,在execute()方法裡面回調傳入的方法。在回調方法裡面即根據傳入的 PreparedStatement 執行 查詢操作,返回結果。而 PreparedStatement 的獲取是在調用回調方法的客戶端實現即在execute()方法裡面獲取,並作為參數傳給回調方法。
public Object doInPreparedStatement(PreparedStatement ps) throws SQLException {
ResultSet rs = null;
try {
if (pss != null) {
pss.setValues(ps);
}
if (getFetchSize() > 0) {
ps.setFetchSize(getFetchSize());
}
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();
}
}
}
});
}

那麼在execue()方法裡面是怎樣回調的呢?下面看看execue()方法:

public Object execute(PreparedStatementCreator psc, PreparedStatementCallback action) {
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);
DataSourceUtils.applyTransactionTimeout(ps, getDataSource());
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) {
throw getExceptionTranslator().translate(
"executing PreparedStatementCallback [" + psc + "]", getSql(psc), ex);
}
finally {
if (psc instanceof ParameterDisposer) {
((ParameterDisposer) psc).cleanupParameters();
}
JdbcUtils.closeStatement(ps);
DataSourceUtils.closeConnectionIfNecessary(con, getDataSource());
}
}

添加刪除的操作類似,只是他們的實現都在以execute命名的方法裡面。

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 execute(final StatementCallback action) {
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();
DataSourceUtils.applyTransactionTimeout(stmt, getDataSource());
Statement stmtToUse = stmt;
if (this.nativeJdbcExtractor != null) {
stmtToUse = this.nativeJdbcExtractor.getNativeStatement(stmt);
}
Object result = action.doInStatement(stmtToUse);
SQLWarning warning = stmt.getWarnings();
throwExceptionOnWarningIfNotIgnoringWarnings(warning);
return result;
}
catch (SQLException ex) {
throw getExceptionTranslator().translate("executing StatementCallback", getSql(action), ex);
}
finally {
//這裡就是我們自己寫程序的時候需要寫的關於數據庫鏈接的關閉操作
JdbcUtils.closeStatement(stmt);
DataSourceUtils.closeConnectionIfNecessary(con, getDataSource());
}
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved