1.先复习下jdbc
2.spring-jdbc
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<!--定义数据源,这里定义spring-jdbc的DriverManagerDataSource-->
<bean id="springDSN" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="jdbc:mysql://...."/>
<property name="username" value="..."></property>
<property name="password" value="..."></property>
</bean>
<!--操作JDBC的类-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="springDSN"/>
</bean>
<bean id="testDao" class="TestDao">
<property name="jdbcTem" ref="jdbcTemplate"/>
</bean>
</beans>
public class TestDao { private JdbcTemplate jdbcT; public void setJdbcTem(JdbcTemplate jdbc){ this.jdbcT = jdbc; } public void selectName() { String sql = "select * from table where id = 19"; List list = jdbcT.queryForList(sql); System.out.println(list.get(0)); } }
跟踪org.springframework.jdbc.core.JdbcTemplate
@Override public List<Map<String, Object>> queryForList(String sql) throws DataAccessException { return query(sql, getColumnMapRowMapper()); } @Override public <T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException { return query(sql, new RowMapperResultSetExtractor<T>(rowMapper)); } @Override public <T> T query(final String sql, final ResultSetExtractor<T> 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<T>, SqlProvider { @Override public T 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); } } @Override public String getSql() { return sql; } } return execute(new QueryStatementCallback()); } @Override public <T> T execute(StatementCallback<T> 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); } T result = action.doInStatement(stmtToUse); handleWarnings(stmt); 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()); } }
跟踪代码,先看看DriverManagerDataSource获取链接,用的是DriverManager.getConnection
/** * Getting a Connection using the nasty static from DriverManager is extracted * into a protected method to allow for easy unit testing. * @see java.sql.DriverManager#getConnection(String, java.util.Properties) */ protected Connection getConnectionFromDriverManager(String url, Properties props) throws SQLException { return DriverManager.getConnection(url, props); }
再看看它处理resultSet
public class RowMapperResultSetExtractor<T> implements ResultSetExtractor<List<T>> { @Override public List<T> extractData(ResultSet rs) throws SQLException { List<T> results = (this.rowsExpected > 0 ? new ArrayList<T>(this.rowsExpected) : new ArrayList<T>()); int rowNum = 0; while (rs.next()) { results.add(this.rowMapper.mapRow(rs, rowNum++)); } return results; } }
public class ColumnMapRowMapper implements RowMapper<Map<String, Object>> { @Override public Map<String, Object> mapRow(ResultSet rs, int rowNum) throws SQLException { ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); Map<String, Object> mapOfColValues = createColumnMap(columnCount); for (int i = 1; i <= columnCount; i++) { String key = getColumnKey(JdbcUtils.lookupColumnName(rsmd, i)); Object obj = getColumnValue(rs, i); mapOfColValues.put(key, obj); } return mapOfColValues; } }