解析Spring的JdbcTemplate
下面就以这个例子解析:
JdbcTemplate 类里面的
调用了 JdbcTemplate里的
调用了 JdbcTemplate里的 getColumnMapRowMapper()
现在我们知道了query(sql, getColumnMapRowMapper());
里面getColumnMapRowMapper()传的是ColumnMapRowMapper
继续说到 ColumnMapRowMapper实现了RowMapper接口
这里面使用了ColumnMapRowMapper作为参数构造了一个RowMapperResultSetExtractor对象作为入参
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 _cls1QueryStatementCallback
implements StatementCallback, SqlProvider
{
public Object doInStatement(Statement stmt)
throws SQLException
{
ResultSet rs = null;
Object obj;
try
{
rs = stmt.executeQuery(sql);
ResultSet rsToUse = rs;
if(nativeJdbcExtractor != null)
rsToUse = nativeJdbcExtractor.getNativeResultSet(rs);
obj = rse.extractData(rsToUse);
}
finally
{
JdbcUtils.closeResultSet(rs);
}
return obj;
}
public String getSql()
{
return sql;
}
_cls1QueryStatementCallback()
{
super();
}
}
return execute(new _cls1QueryStatementCallback());
}
其实不用看里面的内部类 里面方法就一个参数就是 上面方法里面的内部类
他调用了
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
{
Object obj;
try
{
Connection conToUse = con;
if(nativeJdbcExtractor != null && nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements())
conToUse = nativeJdbcExtractor.getNativeConnection(con);
stmt = conToUse.createStatement();
applyStatementSettings(stmt);
Statement stmtToUse = stmt;
if(nativeJdbcExtractor != null)
stmtToUse = nativeJdbcExtractor.getNativeStatement(stmt);
Object result = action.doInStatement(stmtToUse);
handleWarnings(stmt);
obj = result;
}
catch(SQLException ex)
{
JdbcUtils.closeStatement(stmt);
stmt = null;
DataSourceUtils.releaseConnection(con, getDataSource());
con = null;
throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex);
}
return obj;
}
finally
{
JdbcUtils.closeStatement(stmt);
DataSourceUtils.releaseConnection(con, getDataSource());
}
}
里面就是 Object result = action.doInStatement(stmtToUse); 注意这里的stmtToUse是通过工厂方法创建出来的preparestatement
现在我们回过去看 doInStatement()
它里面就是通过preparestatement获取ResultSet
然后对ResultSet rsToUse进行处理
obj = rse.extractData(rsToUse);
这里我们应该知道rse是ColumnMapRowMapper作为参数构造了一个RowMapperResultSetExtractor对象(前面有介绍可以去看看)
那么我们来看
没错他又调用了ColumnMapRowMapper的方法
我们看一下 rowMapper.mapRow(rs, rowNum++)是什么
现在开始打开ColumnMapRowMapper类了
JdbcUtils.lookupColumnName(rsmd, i)是干了什么呢我们来看一下
果然最后返回的是一个List<Map<Sting,object>>的东西
也就是list装着 每一列 这个列是用map的方式来储存内容的