Search in sources :

Example 1 with ColumnMapper

use of org.jdbi.v3.core.mapper.ColumnMapper in project jdbi by jdbi.

the class BeanMapper method specialize0.

private RowMapper<T> specialize0(ResultSet rs, StatementContext ctx, List<String> columnNames, List<ColumnNameMatcher> columnNameMatchers, List<String> unmatchedColumns) throws SQLException {
    final List<RowMapper<?>> mappers = new ArrayList<>();
    final List<PropertyDescriptor> properties = new ArrayList<>();
    for (PropertyDescriptor descriptor : info.getPropertyDescriptors()) {
        Nested anno = Stream.of(descriptor.getReadMethod(), descriptor.getWriteMethod()).filter(Objects::nonNull).map(m -> m.getAnnotation(Nested.class)).filter(Objects::nonNull).findFirst().orElse(null);
        if (anno == null) {
            String paramName = prefix + paramName(descriptor);
            findColumnIndex(paramName, columnNames, columnNameMatchers, () -> debugName(descriptor)).ifPresent(index -> {
                Type type = descriptor.getReadMethod().getGenericReturnType();
                ColumnMapper<?> mapper = ctx.findColumnMapperFor(type).orElse((r, n, c) -> r.getObject(n));
                mappers.add(new SingleColumnMapper<>(mapper, index + 1));
                properties.add(descriptor);
                unmatchedColumns.remove(columnNames.get(index));
            });
        } else {
            String nestedPrefix = prefix + anno.value();
            RowMapper<?> nestedMapper = nestedMappers.computeIfAbsent(descriptor, d -> new BeanMapper<>(d.getPropertyType(), nestedPrefix)).specialize0(rs, ctx, columnNames, columnNameMatchers, unmatchedColumns);
            mappers.add(nestedMapper);
            properties.add(descriptor);
        }
    }
    if (mappers.isEmpty() && columnNames.size() > 0) {
        throw new IllegalArgumentException(String.format("Mapping bean type %s " + "didn't find any matching columns in result set", type));
    }
    return (r, c) -> {
        T bean = construct();
        for (int i = 0; i < mappers.size(); i++) {
            RowMapper<?> mapper = mappers.get(i);
            PropertyDescriptor property = properties.get(i);
            Object value = mapper.map(r, ctx);
            writeProperty(bean, property, value);
        }
        return bean;
    };
}
Also used : ReflectionMapperUtil.getColumnNames(org.jdbi.v3.core.mapper.reflect.ReflectionMapperUtil.getColumnNames) RowMapperFactory(org.jdbi.v3.core.mapper.RowMapperFactory) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Nested(org.jdbi.v3.core.mapper.Nested) SingleColumnMapper(org.jdbi.v3.core.mapper.SingleColumnMapper) IntrospectionException(java.beans.IntrospectionException) InvocationTargetException(java.lang.reflect.InvocationTargetException) ArrayList(java.util.ArrayList) StatementContext(org.jdbi.v3.core.statement.StatementContext) Objects(java.util.Objects) Introspector(java.beans.Introspector) SQLException(java.sql.SQLException) List(java.util.List) Stream(java.util.stream.Stream) Type(java.lang.reflect.Type) PropertyDescriptor(java.beans.PropertyDescriptor) ResultSet(java.sql.ResultSet) BeanInfo(java.beans.BeanInfo) Map(java.util.Map) ReflectionMapperUtil.findColumnIndex(org.jdbi.v3.core.mapper.reflect.ReflectionMapperUtil.findColumnIndex) ColumnMapper(org.jdbi.v3.core.mapper.ColumnMapper) RowMapper(org.jdbi.v3.core.mapper.RowMapper) PropertyDescriptor(java.beans.PropertyDescriptor) ArrayList(java.util.ArrayList) Nested(org.jdbi.v3.core.mapper.Nested) Type(java.lang.reflect.Type) Objects(java.util.Objects) RowMapper(org.jdbi.v3.core.mapper.RowMapper)

Example 2 with ColumnMapper

use of org.jdbi.v3.core.mapper.ColumnMapper in project jdbi by jdbi.

the class SqlArrayMapperFactory method build.

@Override
@SuppressWarnings("unchecked")
public Optional<ColumnMapper<?>> build(Type type, ConfigRegistry config) {
    final Class<?> erasedType = GenericTypes.getErasedType(type);
    if (erasedType.isArray()) {
        Class<?> elementType = erasedType.getComponentType();
        return elementTypeMapper(elementType, config).map(elementMapper -> new ArrayColumnMapper(elementMapper, elementType));
    }
    JdbiCollectors collectorRegistry = config.get(JdbiCollectors.class);
    return collectorRegistry.findFor(type).flatMap(collector -> collectorRegistry.findElementTypeFor(type).flatMap(elementType -> elementTypeMapper(elementType, config)).map(elementMapper -> new CollectorColumnMapper(elementMapper, collector)));
}
Also used : JdbiCollectors(org.jdbi.v3.core.collector.JdbiCollectors) Type(java.lang.reflect.Type) ColumnMappers(org.jdbi.v3.core.mapper.ColumnMappers) ColumnMapper(org.jdbi.v3.core.mapper.ColumnMapper) Optional(java.util.Optional) GenericTypes(org.jdbi.v3.core.generic.GenericTypes) ColumnMapperFactory(org.jdbi.v3.core.mapper.ColumnMapperFactory) ConfigRegistry(org.jdbi.v3.core.config.ConfigRegistry) JdbiCollectors(org.jdbi.v3.core.collector.JdbiCollectors)

Example 3 with ColumnMapper

use of org.jdbi.v3.core.mapper.ColumnMapper in project jdbi by jdbi.

the class JpaMapper method specialize.

@Override
public RowMapper<C> specialize(ResultSet rs, StatementContext ctx) throws SQLException {
    Constructor<C> constructor;
    try {
        constructor = clazz.getDeclaredConstructor();
    } catch (ReflectiveOperationException e) {
        throw new EntityMemberAccessException("Unable to get constructor for " + clazz, e);
    }
    constructor.setAccessible(true);
    List<MemberSetter<C>> setters = new ArrayList<>();
    for (int colIndex = rs.getMetaData().getColumnCount(); colIndex >= 1; colIndex--) {
        String columnLabel = rs.getMetaData().getColumnLabel(colIndex);
        JpaMember member = jpaClass.lookupMember(columnLabel);
        if (member != null) {
            Type memberType = member.getType();
            ColumnMapper<?> columnMapper = ctx.findColumnMapperFor(memberType).orElseThrow(() -> new NoSuchMapperException("No column mapper for " + memberType));
            final int columnIndex = colIndex;
            setters.add(obj -> member.write(obj, columnMapper.map(rs, columnIndex, ctx)));
        }
    }
    return (r, c) -> {
        C obj;
        try {
            obj = constructor.newInstance();
        } catch (ReflectiveOperationException e) {
            throw new EntityMemberAccessException("Unable to invoke " + constructor, e);
        }
        for (MemberSetter<C> setter : setters) {
            setter.mapAndSetMember(obj);
        }
        return obj;
    };
}
Also used : SQLException(java.sql.SQLException) List(java.util.List) Type(java.lang.reflect.Type) ResultSet(java.sql.ResultSet) ColumnMapper(org.jdbi.v3.core.mapper.ColumnMapper) JpaMember(org.jdbi.v3.jpa.internal.JpaMember) NoSuchMapperException(org.jdbi.v3.core.mapper.NoSuchMapperException) Constructor(java.lang.reflect.Constructor) ArrayList(java.util.ArrayList) RowMapper(org.jdbi.v3.core.mapper.RowMapper) StatementContext(org.jdbi.v3.core.statement.StatementContext) JpaClass(org.jdbi.v3.jpa.internal.JpaClass) ArrayList(java.util.ArrayList) NoSuchMapperException(org.jdbi.v3.core.mapper.NoSuchMapperException) Type(java.lang.reflect.Type) JpaMember(org.jdbi.v3.jpa.internal.JpaMember)

Example 4 with ColumnMapper

use of org.jdbi.v3.core.mapper.ColumnMapper in project jdbi by jdbi.

the class StatementContextTest method testMapperForDelegatesToRegistry.

@Test
public void testMapperForDelegatesToRegistry() {
    ColumnMapper<Foo> mapper = new FooMapper();
    ConfigRegistry config = new ConfigRegistry();
    config.get(ColumnMappers.class).register(mapper);
    final StatementContext context = StatementContextAccess.createContext(config);
    assertThat(context.findColumnMapperFor(Foo.class)).contains(mapper);
}
Also used : ConfigRegistry(org.jdbi.v3.core.config.ConfigRegistry) ColumnMappers(org.jdbi.v3.core.mapper.ColumnMappers) Test(org.junit.Test)

Example 5 with ColumnMapper

use of org.jdbi.v3.core.mapper.ColumnMapper in project jdbi by jdbi.

the class FieldMapper method specialize0.

private RowMapper<T> specialize0(ResultSet rs, StatementContext ctx, List<String> columnNames, List<ColumnNameMatcher> columnNameMatchers, List<String> unmatchedColumns) throws SQLException {
    final List<RowMapper<?>> mappers = new ArrayList<>();
    final List<Field> fields = new ArrayList<>();
    for (Class<?> aType = type; aType != null; aType = aType.getSuperclass()) {
        for (Field field : aType.getDeclaredFields()) {
            Nested anno = field.getAnnotation(Nested.class);
            if (anno == null) {
                String paramName = prefix + paramName(field);
                findColumnIndex(paramName, columnNames, columnNameMatchers, () -> debugName(field)).ifPresent(index -> {
                    Type type = field.getGenericType();
                    ColumnMapper<?> mapper = ctx.findColumnMapperFor(type).orElse((r, n, c) -> rs.getObject(n));
                    mappers.add(new SingleColumnMapper(mapper, index + 1));
                    fields.add(field);
                    unmatchedColumns.remove(columnNames.get(index));
                });
            } else {
                String nestedPrefix = prefix + anno.value().toLowerCase();
                RowMapper<?> mapper = nestedMappers.computeIfAbsent(field, f -> new FieldMapper<>(field.getType(), nestedPrefix)).specialize0(rs, ctx, columnNames, columnNameMatchers, unmatchedColumns);
                mappers.add(mapper);
                fields.add(field);
            }
        }
    }
    if (mappers.isEmpty() && columnNames.size() > 0) {
        throw new IllegalArgumentException(String.format("Mapping fields for type %s " + "didn't find any matching columns in result set", type));
    }
    return (r, c) -> {
        T obj = construct();
        for (int i = 0; i < mappers.size(); i++) {
            RowMapper<?> mapper = mappers.get(i);
            Field field = fields.get(i);
            Object value = mapper.map(rs, ctx);
            writeField(obj, field, value);
        }
        return obj;
    };
}
Also used : ReflectionMapperUtil.getColumnNames(org.jdbi.v3.core.mapper.reflect.ReflectionMapperUtil.getColumnNames) RowMapperFactory(org.jdbi.v3.core.mapper.RowMapperFactory) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Nested(org.jdbi.v3.core.mapper.Nested) Field(java.lang.reflect.Field) SingleColumnMapper(org.jdbi.v3.core.mapper.SingleColumnMapper) ArrayList(java.util.ArrayList) StatementContext(org.jdbi.v3.core.statement.StatementContext) SQLException(java.sql.SQLException) List(java.util.List) Type(java.lang.reflect.Type) ResultSet(java.sql.ResultSet) Map(java.util.Map) ReflectionMapperUtil.findColumnIndex(org.jdbi.v3.core.mapper.reflect.ReflectionMapperUtil.findColumnIndex) ColumnMapper(org.jdbi.v3.core.mapper.ColumnMapper) Optional(java.util.Optional) RowMapper(org.jdbi.v3.core.mapper.RowMapper) SingleColumnMapper(org.jdbi.v3.core.mapper.SingleColumnMapper) ArrayList(java.util.ArrayList) Nested(org.jdbi.v3.core.mapper.Nested) Field(java.lang.reflect.Field) Type(java.lang.reflect.Type) RowMapper(org.jdbi.v3.core.mapper.RowMapper)

Aggregations

Type (java.lang.reflect.Type)4 ColumnMapper (org.jdbi.v3.core.mapper.ColumnMapper)4 ResultSet (java.sql.ResultSet)3 SQLException (java.sql.SQLException)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3 RowMapper (org.jdbi.v3.core.mapper.RowMapper)3 StatementContext (org.jdbi.v3.core.statement.StatementContext)3 Map (java.util.Map)2 Optional (java.util.Optional)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 ConfigRegistry (org.jdbi.v3.core.config.ConfigRegistry)2 ColumnMappers (org.jdbi.v3.core.mapper.ColumnMappers)2 Nested (org.jdbi.v3.core.mapper.Nested)2 RowMapperFactory (org.jdbi.v3.core.mapper.RowMapperFactory)2 SingleColumnMapper (org.jdbi.v3.core.mapper.SingleColumnMapper)2 ReflectionMapperUtil.findColumnIndex (org.jdbi.v3.core.mapper.reflect.ReflectionMapperUtil.findColumnIndex)2 ReflectionMapperUtil.getColumnNames (org.jdbi.v3.core.mapper.reflect.ReflectionMapperUtil.getColumnNames)2 BeanInfo (java.beans.BeanInfo)1 IntrospectionException (java.beans.IntrospectionException)1