![JAR search and dependency download from the Maven repository](/logo.png)
org.sfm.jdbc.JdbcMapperBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of simpleFlatMapper Show documentation
Show all versions of simpleFlatMapper Show documentation
Java library to map flat record - ResultSet, csv - to java object with minimum configuration and low footprint.
package org.sfm.jdbc;
import org.sfm.jdbc.impl.*;
import org.sfm.jdbc.impl.getter.ResultSetGetterFactory;
import org.sfm.map.*;
import org.sfm.map.impl.*;
import org.sfm.reflect.Instantiator;
import org.sfm.reflect.ReflectionService;
import org.sfm.reflect.TypeReference;
import org.sfm.reflect.meta.ClassMeta;
import org.sfm.reflect.meta.PropertyNameMatcherFactory;
import org.sfm.tuples.Tuple2;
import org.sfm.utils.ErrorHelper;
import java.lang.reflect.Type;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
/**
* @param the targeted type of the mapper
*/
public final class JdbcMapperBuilder extends AbstractFieldMapperMapperBuilder {
public static final int NO_ASM_MAPPER_THRESHOLD = 792; // see https://github.com/arnaudroger/SimpleFlatMapper/issues/152
public static final JdbcColumnKey[] EMPTY_COLUMN_KEYS = new JdbcColumnKey[0];
private int calculatedIndex = 1;
private RowHandlerErrorHandler jdbcMapperErrorHandler = new RethrowRowHandlerErrorHandler();
private final boolean failOnAsm;
private final int asmMapperNbFieldsLimit;
/**
* Build a new JdbcMapperBuilder targeting the type specified by the TypeReference. The TypeReference
* allow you to provide a generic type with check of T
* new TypeReference<List<String>>() {}
*
* @param target the TypeReference to the type T to map to
*/
public JdbcMapperBuilder(final TypeReference target) {
this(target.getType());
}
/**
* Build a new JdbcMapperBuilder targeting the specified type.
*
* @param target the type
*/
public JdbcMapperBuilder(final Type target) {
this(target, ReflectionService.newInstance());
}
/**
* Build a new JdbcMapperBuilder targeting the specified type with the specified ReflectionService.
*
* @param target the type
* @param reflectService the ReflectionService
*/
public JdbcMapperBuilder(final Type target, ReflectionService reflectService) {
this(reflectService.getClassMeta(target),
new RethrowMapperBuilderErrorHandler(),
new IdentityFieldMapperColumnDefinitionProvider(),
new DefaultPropertyNameMatcherFactory(),
new ResultSetGetterFactory(),
false,
NO_ASM_MAPPER_THRESHOLD,
new JdbcMappingContextFactoryBuilder());
}
/**
* @param classMeta the meta for the target class.
* @param mapperBuilderErrorHandler the error handler.
* @param columnDefinitions the predefined ColumnDefinition.
* @param propertyNameMatcherFactory the PropertyNameMatcher factory.
* @param getterFactory the Getter factory.
* @param failOnAsm should we fail on asm generation.
* @param parentBuilder the parent builder, null if none.
*/
public JdbcMapperBuilder(final ClassMeta classMeta, final MapperBuilderErrorHandler mapperBuilderErrorHandler,
final ColumnDefinitionProvider, JdbcColumnKey> columnDefinitions,
PropertyNameMatcherFactory propertyNameMatcherFactory,
GetterFactory getterFactory, boolean failOnAsm, int asmMapperNbFieldsLimit,
MappingContextFactoryBuilder parentBuilder) {
super(ResultSet.class, classMeta, getterFactory, new ResultSetFieldMapperFactory(getterFactory), columnDefinitions, propertyNameMatcherFactory, mapperBuilderErrorHandler, parentBuilder);
this.failOnAsm = failOnAsm;
this.asmMapperNbFieldsLimit = asmMapperNbFieldsLimit;
}
/**
* @return a new instance of the mapper based on the current state of the builder.
*/
@Override
public JdbcMapper mapper() {
JdbcMapper mapper = buildMapper();
if (!mappingContextFactoryBuilder.isRoot()
|| mappingContextFactoryBuilder.hasNoDependentKeys()) {
return mapper;
} else {
return new JoinJdbcMapper(mapper, jdbcMapperErrorHandler);
}
}
private JdbcMapper buildMapper() {
FieldMapper[] fields = fields();
Tuple2[], Instantiator> constructorFieldMappersAndInstantiator = getConstructorFieldMappersAndInstantiator();
MappingContextFactory mappingContextFactory = null;
if (mappingContextFactoryBuilder.isRoot()) {
mappingContextFactory = mappingContextFactoryBuilder.newFactory();
}
if (isEligibleForAsmMapper()) {
try {
return reflectionService.getAsmFactory().createJdbcMapper(
getKeys(),
fields, constructorFieldMappersAndInstantiator.first(),
constructorFieldMappersAndInstantiator.second(),
getTargetClass(), jdbcMapperErrorHandler, mappingContextFactory);
} catch (Exception e) {
if (failOnAsm) {
return ErrorHelper.rethrow(e);
} else {
return new JdbcMapperImpl(fields, constructorFieldMappersAndInstantiator.first(), constructorFieldMappersAndInstantiator.second(), jdbcMapperErrorHandler, mappingContextFactory);
}
}
} else {
return new JdbcMapperImpl(fields, constructorFieldMappersAndInstantiator.first(), constructorFieldMappersAndInstantiator.second(), jdbcMapperErrorHandler, mappingContextFactory);
}
}
private JdbcColumnKey[] getKeys() {
return propertyMappingsBuilder.getKeys().toArray(EMPTY_COLUMN_KEYS);
}
private boolean isEligibleForAsmMapper() {
return reflectionService.isAsmActivated()
&& propertyMappingsBuilder.size() < asmMapperNbFieldsLimit;
}
/**
* add a new mapping to the specified column with a key column definition and an undefined type.
* The index is incremented for each non indexed column mapping.
*
* @param column the column name
* @return the current builder
*/
public JdbcMapperBuilder addKey(String column) {
return addMapping(column, calculatedIndex++, FieldMapperColumnDefinition.key());
}
/**
* add a new mapping to the specified column with an undefined type. The index is incremented for each non indexed column mapping.
*
* @param column the column name
* @return the current builder
*/
public JdbcMapperBuilder addMapping(String column) {
return addMapping(column, calculatedIndex++);
}
/**
* add a new mapping to the specified column with the specified columnDefinition and an undefined type. The index is incremented for each non indexed column mapping.
*
* @param column the column name
* @param columnDefinition the definition
* @return the current builder
*/
public JdbcMapperBuilder addMapping(final String column, final FieldMapperColumnDefinition columnDefinition) {
return addMapping(column, calculatedIndex++, columnDefinition);
}
/**
* add a new mapping to the specified column with the specified index and an undefined type.
*
* @param column the column name
* @param index the column index
* @return the current builder
*/
public JdbcMapperBuilder addMapping(String column, int index) {
return addMapping(column, index, JdbcColumnKey.UNDEFINED_TYPE);
}
/**
* add a new mapping to the specified column with the specified index, specified column definition and an undefined type.
*
* @param column the column name
* @param index the column index
* @param columnDefinition the column definition
* @return the current builder
*/
public JdbcMapperBuilder addMapping(String column, int index, final FieldMapperColumnDefinition columnDefinition) {
return addMapping(column, index, JdbcColumnKey.UNDEFINED_TYPE, columnDefinition);
}
/**
* append a FieldMapper to the mapping list.
*
* @param mapper the field mapper
* @return the current builder
*/
public JdbcMapperBuilder addMapper(FieldMapper mapper) {
_addMapper(mapper);
return this;
}
/**
* add a new mapping to the specified column with the specified index and the specified type.
*
* @param column the column name
* @param index the column index
* @param sqlType the column type, @see java.sql.Types
* @return the current builder
*/
public JdbcMapperBuilder addMapping(final String column, final int index, final int sqlType) {
addMapping(column, index, sqlType, FieldMapperColumnDefinition.identity());
return this;
}
/**
* add a new mapping to the specified column with the specified index, the specified type.
*
* @param column the column name
* @param index the column index
* @param sqlType the column type, @see java.sql.Types
* @param columnDefinition the column definition
* @return the current builder
*/
public JdbcMapperBuilder addMapping(final String column, final int index, final int sqlType, FieldMapperColumnDefinition columnDefinition) {
_addMapping(new JdbcColumnKey(column, index, sqlType), columnDefinition);
return this;
}
/**
* add the all the column present in the metaData
*
* @param metaData the metaDAta
* @return the current builder
* @throws SQLException when an error occurs getting the metaData
*/
public JdbcMapperBuilder addMapping(final ResultSetMetaData metaData) throws SQLException {
for (int i = 1; i <= metaData.getColumnCount(); i++) {
addMapping(metaData.getColumnLabel(i), i, metaData.getColumnType(i));
}
return this;
}
@Override
protected AbstractFieldMapperMapperBuilder newSubBuilder(Type type, ClassMeta classMeta, MappingContextFactoryBuilder mappingContextFactoryBuilder) {
return new JdbcMapperBuilder(classMeta, mapperBuilderErrorHandler, columnDefinitions, propertyNameMatcherFactory,
new ResultSetGetterFactory(), failOnAsm, asmMapperNbFieldsLimit, mappingContextFactoryBuilder);
}
/**
* the FieldMapperErrorHandler is called when a error occurred when mapping a field from the source to the target.
* By default it just throw the Exception.
* @param errorHandler the new FieldMapperErrorHandler
* @return the current builder
*/
public JdbcMapperBuilder fieldMapperErrorHandler(FieldMapperErrorHandler errorHandler) {
setFieldMapperErrorHandler(errorHandler);
return this;
}
/**
* the RowHandlerErrorHandler is called when an exception is thrown by the RowHandler in the forEach call.
* @param jdbcMapperErrorHandler the new RowHandlerErrorHandler
* @return the current builder
*/
public JdbcMapperBuilder jdbcMapperErrorHandler(RowHandlerErrorHandler jdbcMapperErrorHandler) {
this.jdbcMapperErrorHandler = jdbcMapperErrorHandler;
return this;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy