All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.arakelian.jdbc.handler.ObjectMapperHandler Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.arakelian.jdbc.handler;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.arakelian.jackson.utils.JacksonUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;

/**
 * ResultSetHandler implementation that converts the next ResultSet row
 * into a JavaBean.
 *
 * @param 
 *            the type of bean that we return
 */
public class ObjectMapperHandler implements ResultSetHandler {
    /**
     * The Class of beans produced by this handler.
     */
    private final Class type;

    private final ObjectMapper mapper;

    public ObjectMapperHandler(final Class type) {
        this(type, JacksonUtils.getObjectMapper());
    }

    public ObjectMapperHandler(final Class type, final ObjectMapper mapper) {
        this.type = Preconditions.checkNotNull(type);
        this.mapper = Preconditions.checkNotNull(mapper);
    }

    public Class getType() {
        return type;
    }

    /**
     * Convert the first row of the ResultSet into a bean with the Class
     * given in the constructor.
     *
     * @param rs
     *            ResultSet to process.
     * @return An initialized JavaBean or null if there were no rows in the
     *         ResultSet.
     *
     * @throws SQLException
     *             if a database access error occurs
     */
    @Override
    public T handle(final ResultSet rs, final ResultSetMetaData rsmd) throws SQLException {
        if (rs.next()) {
            return createBean(rs, type);
        } else {
            return null;
        }
    }

    @Override
    public boolean wasLast(final T result) {
        return result == null;
    }

    /**
     * Creates a new object and initializes its fields from the ResultSet.
     *
     * @param rs
     *            The result set.
     * @param type
     *            The bean type (the return type of the object).
     * @param props
     *            The property descriptors.
     * @param columnToProperty
     *            The column indices in the result set.
     * @return An initialized object.
     * @throws SQLException
     *             if a database error occurs.
     */
    private T createBean(final ResultSet rs, final Class type) throws SQLException {
        final ResultSetMetaData rsmd = rs.getMetaData();

        final Map map = Maps.newLinkedHashMap();
        final int columnCount = rsmd.getColumnCount();
        for (int column = 1; column <= columnCount; column++) {
            final Object value = processColumn(rs, rsmd, column);
            // note: getColumnName() returns original column name, whereas getColumnLabel() will
            // return the alias if any
            final String name = StringUtils
                    .defaultIfEmpty(rsmd.getColumnLabel(column), rsmd.getColumnName(column));
            map.put(name, value);
        }

        final T bean = mapper.convertValue(map, type);
        return bean;
    }

    /**
     * Convert a ResultSet column into an object. Simple implementations could just
     * call rs.getObject(index) while more complex implementations could perform type
     * manipulation.
     *
     * @param rs
     *            The ResultSet currently being processed. It is positioned on a valid
     *            row before being passed into this method.
     * @param rsmd
     *            ResultSet metadata
     * @param column
     *            The current column index being processed.
     *
     * @throws SQLException
     *             if a database access error occurs
     *
     * @return The object from the ResultSet at the given column index after optional
     *         type processing or null if the column value was SQL NULL.
     */
    protected Object processColumn(final ResultSet rs, final ResultSetMetaData rsmd, final int column)
            throws SQLException {
        return rs.getObject(column);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy