返回单列的RowMapper实现

import java.math.BigDecimal;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

import org.springframework.jdbc.support.JdbcUtils;

import com.huawei.widget.commons.dao.DBException;
import com.huawei.widget.commons.dao.RowMapper;
import com.huawei.widget.commons.dao.util.NumberUtils;

/**
 * 返回单列的RowMapper实现
 *
 * @author g00106664
 * @version C02 2009-4-27
 * @since OpenEye WIDGET_SRV V100R001C02
 */
@SuppressWarnings("unchecked")
public class SingleColumnRowMapper implements RowMapper
{

    /**
     * 需转换的类型
     */
    private Class requiredType;

    /**
     * Create a new SingleColumnRowMapper.
     *
     * @see #setRequiredType
     */
    public SingleColumnRowMapper()
    {
    }

    /**
     * Create a new SingleColumnRowMapper.
     *
     * @param requiredType
     *            the type that each result object is expected to match
     */
    public SingleColumnRowMapper(Class requiredType)
    {
        this.requiredType = requiredType;
    }

    /**
     * Set the type that each result object is expected to match.
     * <p>
     * If not specified, the column value will be exposed as returned by the
     * JDBC driver.
     *
     * @param requiredType
     *            所需类型
     */
    public void setRequiredType(Class requiredType)
    {
        this.requiredType = requiredType;
    }

    /**
     * 将每行数据映射为实体类
     *
     * @param rs
     *            ResultSet
     * @param rowNum
     *            the row num
     * @return the t
     * @throws java.sql.SQLException
     *             the SQL exception
     * @see com.huawei.widget.db.RowMapper#mapRow(ResultSet, int)
     */
    public Object mapRow(ResultSet rs, int rowNum) throws SQLException
    {
        // Validate column count.
        ResultSetMetaData rsmd = rs.getMetaData();
        int nrOfColumns = rsmd.getColumnCount();
        if (nrOfColumns != 1)
        {
            throw new DBException("Incorrect column count: expected " + 1
                    + ", actual " + nrOfColumns);
        }

        // Extract column value from JDBC ResultSet
        Object result = getColumnValue(rs, 1, this.requiredType);
        if (result != null && this.requiredType != null
                && !this.requiredType.isInstance(result))
        {
            // Extracted value does not match already: try to convert it.
            try
            {
                return convertValueToRequiredType(result, this.requiredType);
            }
            catch (IllegalArgumentException ex)
            {
                throw new DBException("Type mismatch affecting row number "
                        + rowNum + " and column type '"
                        + rsmd.getColumnTypeName(1) + "': " + ex.getMessage());
            }
        }
        return result;
    }

    /**
     * Retrieve a JDBC object value for the specified column.
     * <p>
     * The default implementation calls <code>ResultSet.getString(index)</code>
     * etc for all standard value types (String, Boolean, number types, date
     * types, etc). It calls <code>ResultSet.getObject(index)</code> else.
     * <p>
     * If no required type has been specified, this method delegates to
     * <code>getColumnValue(rs, index)</code>, which basically calls
     * <code>ResultSet.getObject(index)</code> but applies some additional
     * default conversion to appropriate value types.
     * <p>
     * Explicit extraction of a String is necessary to properly extract an
     * Oracle RAW value as a String, for example. For the other given types, it
     * is also recommendable to extract the desired types explicitly, to let the
     * JDBC driver perform appropriate (potentially database-specific)
     * conversion.
     *
     * @param rs
     *            is the ResultSet holding the data
     * @param index
     *            is the column index
     * @param requiredType
     *            the type that each result object is expected to match (or
     *            <code>null</code> if none specified)
     * @return the Object value
     * @throws java.sql.SQLException
     *             抛出异常
     * @see java.sql.ResultSet#getString(int)
     * @see java.sql.ResultSet#getObject(int)
     * @see #getColumnValue(java.sql.ResultSet, int)
     */
    protected Object getColumnValue(ResultSet rs, int index, Class requiredType)
            throws SQLException
    {
        if (requiredType != null)
        {
            Object value = null;
            boolean wasNullCheck = false;

            // Explicitly extract typed value, as far as possible.
            if (String.class.equals(requiredType))
            {
                value = rs.getString(index);
            }
            else if (Boolean.class.equals(requiredType))
            {
                value = (rs.getBoolean(index) ? Boolean.TRUE : Boolean.FALSE);
                wasNullCheck = true;
            }
            else if (Byte.class.equals(requiredType))
            {
                value = Byte.valueOf(rs.getByte(index));
                wasNullCheck = true;
            }
            else if (Short.class.equals(requiredType))
            {
                value = Short.valueOf(rs.getShort(index));
                wasNullCheck = true;
            }
            else if (Integer.class.equals(requiredType))
            {
                value = Integer.valueOf(rs.getInt(index));
                wasNullCheck = true;
            }
            else if (Long.class.equals(requiredType))
            {
                value = Long.valueOf(rs.getLong(index));
                wasNullCheck = true;
            }
            else if (Float.class.equals(requiredType))
            {
                value = Float.valueOf(rs.getFloat(index));
                wasNullCheck = true;
            }
            else if (Double.class.equals(requiredType)
                    || Number.class.equals(requiredType))
            {
                value = Double.valueOf(rs.getDouble(index));
                wasNullCheck = true;
            }
            else if (byte[].class.equals(requiredType))
            {
                value = rs.getBytes(index);
            }
            else if (java.sql.Date.class.equals(requiredType))
            {
                value = rs.getDate(index);
            }
            else if (java.sql.Time.class.equals(requiredType))
            {
                value = rs.getTime(index);
            }
            else if (java.sql.Timestamp.class.equals(requiredType)
                    || java.util.Date.class.equals(requiredType))
            {
                value = rs.getTimestamp(index);
            }
            else if (BigDecimal.class.equals(requiredType))
            {
                value = rs.getBigDecimal(index);
            }
            else if (Blob.class.equals(requiredType))
            {
                value = rs.getBlob(index);
            }
            else if (Clob.class.equals(requiredType))
            {
                value = rs.getClob(index);
            }
            else
            {
                // Some unknown type desired -> rely on getObject.
                value = rs.getObject(index);
            }

            // Perform was-null check if demanded (for results that the
            // JDBC driver returns as primitives).
            if (wasNullCheck && value != null && rs.wasNull())
            {
                value = null;
            }
            return value;
        }

        else
        {
            // No required type specified -> perform default extraction.
            return getColumnValue(rs, index);
        }
    }

    /**
     * Retrieve a JDBC object value for the specified column, using the most
     * appropriate value type. Called if no required type has been specified.
     * <p>
     * The default implementation delegates to
     * <code>JdbcUtils.getResultSetValue()</code>, which uses the
     * <code>ResultSet.getObject(index)</code> method. Additionally, it
     * includes a "hack" to get around Oracle returning a non-standard object
     * for their TIMESTAMP datatype. See the
     * <code>JdbcUtils#getResultSetValue()</code> javadoc for details.
     *
     * @param rs
     *            is the ResultSet holding the data
     * @param index
     *            is the column index
     * @return the Object value
     * @throws java.sql.SQLException
     *             throw
     * @see org.springframework.jdbc.support.JdbcUtils#getResultSetValue(java.sql.ResultSet,
     *      int)
     */
    protected Object getColumnValue(ResultSet rs, int index)
            throws SQLException
    {
        return JdbcUtils.getResultSetValue(rs, index);
    }

    /**
     * Convert the given column value to the specified required type. Only
     * called if the extracted column value does not match already.
     * <p>
     * If the required type is String, the value will simply get stringified via
     * <code>toString()</code>. In case of a Number, the value will be
     * converted into a Number, either through number conversion or through
     * String parsing (depending on the value type).
     *
     * @param value
     *            the column value as extracted from
     *            <code>getColumnValue()</code> (never <code>null</code>)
     * @param requiredType
     *            the type that each result object is expected to match (never
     *            <code>null</code>)
     * @return the converted value
     * @see #getColumnValue(java.sql.ResultSet, int, Class)
     */
    protected Object convertValueToRequiredType(Object value, Class requiredType)
    {
        if (String.class.equals(this.requiredType))
        {
            return value.toString();
        }
        else if (Number.class.isAssignableFrom(this.requiredType))
        {
            if (value instanceof Number)
            {
                // Convert original Number to target Number class.
                return NumberUtils.convertNumberToTargetClass(((Number) value),
                        this.requiredType);
            }
            else
            {
                // Convert stringified value to target Number class.
                return NumberUtils.parseNumber(value.toString(),
                        this.requiredType);
            }
        }
        else
        {
            throw new IllegalArgumentException("Value [" + value
                    + "] is of type [" + value.getClass().getName()
                    + "] and cannot be converted to required type ["
                    + this.requiredType.getName() + "]");
        }
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值