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

win.doyto.query.jdbc.rowmapper.BeanPropertyRowMapper Maven / Gradle / Ivy

The newest version!
// Generated by delombok at Wed Nov 06 09:48:29 UTC 2024
/*
 * Copyright © 2019-2024 Forb Yuan
 *
 * Licensed 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 win.doyto.query.jdbc.rowmapper;

import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import win.doyto.query.sql.RelationalQueryBuilder;
import win.doyto.query.util.ColumnUtil;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.NoSuchElementException;

/**
 * BeanPropertyRowMapper
 *
 * @author f0rb on 2021-10-26
 */
public class BeanPropertyRowMapper implements RowMapper {
    @java.lang.SuppressWarnings("all")
    @lombok.Generated
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(BeanPropertyRowMapper.class);
    private final Class mappedClass;
    private final Map fieldMap = new LinkedHashMap<>();

    public BeanPropertyRowMapper(Class mappedClass) {
        try {
            this.mappedClass = mappedClass;
            BeanInfo beanInfo = Introspector.getBeanInfo(mappedClass);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            Arrays.stream(propertyDescriptors).filter(pd -> pd.getWriteMethod() != null && ColumnUtil.filterForView(FieldUtils.getField(mappedClass, pd.getName(), true))).forEach(pd -> {
                this.fieldMap.put(pd.getName(), pd);
                this.fieldMap.put(pd.getName().toUpperCase(), pd);
                this.fieldMap.put(pd.getName().toLowerCase(), pd);
                String upperSnakeKey = ColumnUtil.camelCaseToUnderscore(pd.getName());
                this.fieldMap.put(upperSnakeKey, pd);
                this.fieldMap.put(upperSnakeKey.toUpperCase(), pd);
            });
        } catch (final java.lang.Throwable $ex) {
            throw lombok.Lombok.sneakyThrow($ex);
        }
    }

    @Override
    public E map(ResultSet rs, int rn) throws SQLException {
        try {
            E entity = mappedClass.getDeclaredConstructor().newInstance();
            ResultSetMetaData rsmd = rs.getMetaData();
            for (int i = 0; i++ < rsmd.getColumnCount(); ) {
                String columnLabel = rsmd.getColumnLabel(i);
                PropertyDescriptor pd = fieldMap.get(columnLabel);
                if (pd == null) {
                    if (!RelationalQueryBuilder.KEY_COLUMN.equals(columnLabel)) {
                        log.warn("Column [{}] not found in {}.", columnLabel, fieldMap.keySet());
                    }
                    continue;
                }
                try {
                    Object value = getColumnValue(rs, pd, rsmd.getColumnLabel(i));
                    pd.getWriteMethod().invoke(entity, value);
                } catch (IllegalArgumentException | NoSuchElementException e) {
                    log.error("Fail to get value for [{}]: {}", pd.getName(), e.getMessage());
                } catch (IllegalAccessException | InvocationTargetException e) {
                    log.error("Fail to invoke write method: {}-{}", pd.getWriteMethod().getName(), e.getMessage());
                }
            }
            return entity;
        } catch (final java.lang.Throwable $ex) {
            throw lombok.Lombok.sneakyThrow($ex);
        }
    }

    protected Object getColumnValue(ResultSet rs, PropertyDescriptor pd, String columnLabel) throws SQLException {
        try {
            if (rs.getObject(columnLabel) == null) return null;
        } catch (SQLException e) {
            throw new NoSuchElementException(e);
        }
        Class propertyType = pd.getPropertyType();
        if (propertyType.isEnum()) {
            String value = rs.getString(columnLabel);
            if (NumberUtils.isCreatable(value)) {
                Integer ordinal = NumberUtils.createInteger(value);
                return propertyType.getEnumConstants()[ordinal];
            }
            return stringToEnum(propertyType, value);
        }
        if (propertyType == LocalDateTime.class) {
            Timestamp timestamp = rs.getTimestamp(columnLabel);
            return timestamp != null ? timestamp.toLocalDateTime() : null;
        }
        return rs.getObject(columnLabel, propertyType);
    }

    @SuppressWarnings("unchecked")
    private static > T stringToEnum(Class propertyType, String value) {
        return Enum.valueOf((Class) propertyType, value);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy