001: /*
002: * Copyright 2002-2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.jdbc.core;
018:
019: import java.sql.ResultSet;
020: import java.sql.ResultSetMetaData;
021: import java.sql.SQLException;
022: import java.util.Map;
023:
024: import org.springframework.core.CollectionFactory;
025: import org.springframework.jdbc.support.JdbcUtils;
026:
027: /**
028: * {@link RowMapper} implementation that creates a <code>java.util.Map</code>
029: * for each row, representing all columns as key-value pairs: one
030: * entry for each column, with the column name as key.
031: *
032: * <p>The Map implementation to use and the key to use for each column
033: * in the column Map can be customized through overriding
034: * {@link #createColumnMap} and {@link #getColumnKey}, respectively.
035: *
036: * <p><b>Note:</b> By default, ColumnMapRowMapper will try to build a linked Map
037: * with case-insensitive keys, to preserve column order as well as allow any
038: * casing to be used for column names. This requires Commons Collections on the
039: * classpath (which will be autodetected). Else, the fallback is a standard linked
040: * HashMap, which will still preserve column order but requires the application
041: * to specify the column names in the same casing as exposed by the driver.
042: *
043: * @author Juergen Hoeller
044: * @since 1.2
045: * @see JdbcTemplate#queryForList(String)
046: * @see JdbcTemplate#queryForMap(String)
047: */
048: public class ColumnMapRowMapper implements RowMapper {
049:
050: public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
051: ResultSetMetaData rsmd = rs.getMetaData();
052: int columnCount = rsmd.getColumnCount();
053: Map mapOfColValues = createColumnMap(columnCount);
054: for (int i = 1; i <= columnCount; i++) {
055: String key = getColumnKey(JdbcUtils.lookupColumnName(rsmd,
056: i));
057: Object obj = getColumnValue(rs, i);
058: mapOfColValues.put(key, obj);
059: }
060: return mapOfColValues;
061: }
062:
063: /**
064: * Create a Map instance to be used as column map.
065: * <p>By default, a linked case-insensitive Map will be created if possible,
066: * else a plain HashMap (see Spring's CollectionFactory).
067: * @param columnCount the column count, to be used as initial
068: * capacity for the Map
069: * @return the new Map instance
070: * @see org.springframework.core.CollectionFactory#createLinkedCaseInsensitiveMapIfPossible
071: */
072: protected Map createColumnMap(int columnCount) {
073: return CollectionFactory
074: .createLinkedCaseInsensitiveMapIfPossible(columnCount);
075: }
076:
077: /**
078: * Determine the key to use for the given column in the column Map.
079: * @param columnName the column name as returned by the ResultSet
080: * @return the column key to use
081: * @see java.sql.ResultSetMetaData#getColumnName
082: */
083: protected String getColumnKey(String columnName) {
084: return columnName;
085: }
086:
087: /**
088: * Retrieve a JDBC object value for the specified column.
089: * <p>The default implementation uses the <code>getObject</code> method.
090: * Additionally, this implementation includes a "hack" to get around Oracle
091: * returning a non standard object for their TIMESTAMP datatype.
092: * @param rs is the ResultSet holding the data
093: * @param index is the column index
094: * @return the Object returned
095: * @see org.springframework.jdbc.support.JdbcUtils#getResultSetValue
096: */
097: protected Object getColumnValue(ResultSet rs, int index)
098: throws SQLException {
099: return JdbcUtils.getResultSetValue(rs, index);
100: }
101:
102: }
|