/** * Register a column mapper factory. * <p> * Column mappers may be reused by {@link RowMapper} to map individual columns. * * @param factory the column mapper factory * @return this */ public ColumnMappers register(ColumnMapperFactory factory) { return register(QualifiedColumnMapperFactory.adapt(factory)); }
/** * Obtain a column mapper for the given qualified type. * * @param type the qualified target type to map to * @return a ColumnMapper for the given type, or empty if no column mapper is registered for the given type. */ @Beta public <T> Optional<ColumnMapper<T>> findFor(QualifiedType<T> type) { // ConcurrentHashMap can enter an infinite loop on nested computeIfAbsent calls. // Since column mappers can decorate other column mappers, we have to populate the cache the old fashioned way. // See https://bugs.openjdk.java.net/browse/JDK-8062841, https://bugs.openjdk.java.net/browse/JDK-8142175 @SuppressWarnings("unchecked") ColumnMapper<T> cached = (ColumnMapper<T>) cache.get(type); if (cached != null) { return Optional.of(cached); } Optional<ColumnMapper<T>> mapper = factories.stream() .flatMap(factory -> JdbiOptionals.stream(factory.build(type, registry))) .findFirst() .map(m -> (ColumnMapper<T>) m); mapper.ifPresent(m -> cache.put(type, m)); return mapper; }
/** * Register a column mapper for a given {@link QualifiedType} * Column mappers may be reused by {@link RowMapper} to map individual columns. * * @param type the type to match with equals. * @param mapper the column mapper * @return this */ @Beta public <T> ColumnMappers register(QualifiedType<T> type, ColumnMapper<T> mapper) { return this.register(QualifiedColumnMapperFactory.of(type, mapper)); }