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

org.simpleflatmapper.jdbc.JdbcMapperFactory Maven / Gradle / Ivy

package org.simpleflatmapper.jdbc;

import org.simpleflatmapper.map.ContextualSourceFieldMapper;
import org.simpleflatmapper.map.MapperConfig;
import org.simpleflatmapper.map.MappingContext;
import org.simpleflatmapper.map.getter.ContextualGetterFactory;
import org.simpleflatmapper.map.getter.ContextualGetterFactoryAdapter;
import org.simpleflatmapper.map.mapper.AbstractColumnNameDiscriminatorMapperFactory;
import org.simpleflatmapper.map.mapper.DynamicSourceFieldMapper;
import org.simpleflatmapper.reflect.getter.GetterFactory;
import org.simpleflatmapper.jdbc.impl.JdbcColumnKeyMapperKeyComparator;
import org.simpleflatmapper.jdbc.impl.PreparedStatementSetterFactory;
import org.simpleflatmapper.map.FieldMapper;
import org.simpleflatmapper.map.SetRowMapper;
import org.simpleflatmapper.map.property.FieldMapperColumnDefinition;
import org.simpleflatmapper.reflect.Getter;
import org.simpleflatmapper.map.mapper.AbstractMapperFactory;
import org.simpleflatmapper.map.mapper.ConstantTargetFieldMapperFactoryImpl;
import org.simpleflatmapper.map.mapper.DynamicSetRowMapper;
import org.simpleflatmapper.map.mapper.FieldMapperColumnDefinitionProviderImpl;
import org.simpleflatmapper.map.mapper.MapperKey;
import org.simpleflatmapper.util.TypeHelper;
import org.simpleflatmapper.util.TypeReference;
import org.simpleflatmapper.reflect.meta.ClassMeta;
import org.simpleflatmapper.util.UnaryFactory;
import org.simpleflatmapper.util.UnaryFactoryWithException;

import java.lang.reflect.Type;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

/**
 * JdbcMapperFactory allows you to customise the mappers and create an newInstance of it using a fluent syntax.
 * 

* JdbcMapperFactory is not Thread-Safe but the mappers are. * It is strongly advised to instantiate one jdbcMapper per class for the life of your application. *

* You can instantiate dynamic jdbcMapper which will use the ResultSetMetaData * to figure out the list of the columns or a static one using a builder. *

* * // create a dynamic jdbcMapper targeting MyClass
* JdbcMapperFactory
*     .newInstance()
*     .newMapper(MyClass.class);
*
* // create a static jdbcMapper targeting MyClass
* JdbcMapperFactory
*     .newInstance()
*     .newBuilder(MyClass.class)
*     .addMapping("id")
*     .addMapping("field1")
*     .addMapping("field2")
*     .mapper();
*
*
* */ public final class JdbcMapperFactory extends AbstractColumnNameDiscriminatorMapperFactory { /** * instantiate a new JdbcMapperFactory * @return a new newInstance JdbcMapperFactory */ public static JdbcMapperFactory newInstance() { return new JdbcMapperFactory(); } public static JdbcMapperFactory newInstance( AbstractMapperFactory config) { return new JdbcMapperFactory(config); } private JdbcMapperFactory(AbstractMapperFactory config) { super(config); } private JdbcMapperFactory() { super(new FieldMapperColumnDefinitionProviderImpl(), FieldMapperColumnDefinition.identity(), new ContextualGetterFactoryAdapter(ResultSetGetterFactory.INSTANCE)); } /** * Override the default implementation of the GetterFactory used to get access to value from the ResultSet. * @param getterFactory the getterFactory * @return the current factory */ public JdbcMapperFactory getterFactory(final GetterFactory getterFactory) { return addGetterFactory(new ContextualGetterFactoryAdapter(getterFactory)); } /** * Override the default implementation of the GetterFactory used to get access to value from the ResultSet. * @param getterFactory the getterFactory * @return the current factory */ public JdbcMapperFactory addGetterFactory(final ContextualGetterFactory getterFactory) { return super.addGetterFactory(getterFactory); } /** * Associate the specified FieldMapper for the specified property. * @param key the property * @param fieldMapper the fieldMapper * @return the current factory */ public JdbcMapperFactory addCustomFieldMapper(String key, FieldMapper fieldMapper) { return addColumnDefinition(key, FieldMapperColumnDefinition.customFieldMapperDefinition(fieldMapper)); } /** * Associate the specified Getter for the specified property. * @param key the property * @param getter the getter * @return the current factory */ public JdbcMapperFactory addCustomGetter(String key, Getter getter) { return addColumnDefinition(key, FieldMapperColumnDefinition.customGetter(getter)); } /** * Will create a newInstance of JdbcMapper based on the specified metadata and the target class. * @param target the target class of the jdbcMapper * @param metaData the metadata to create the jdbcMapper from * @param the jdbcMapper target type * @return a jdbcMapper that will map the data represented by the metadata to an newInstance of target * @throws java.sql.SQLException if an error occurs getting the metaData */ public JdbcMapper newMapper(final Class target, final ResultSetMetaData metaData) throws SQLException { JdbcMapperBuilder builder = newBuilder(target); builder.addMapping(metaData); return builder.mapper(); } /** * Will create a newInstance of JdbcMapperBuilder on the specified target class. * @param target the target class * @param the jdbcMapper target type * @return the builder */ public JdbcMapperBuilder newBuilder(final Class target) { return newBuilder((Type)target); } /** * Will create a newInstance of JdbcMapperBuilder on the type T specified by the typeReference. * @param target the typeReference * @param the jdbcMapper target type * @return the builder */ public JdbcMapperBuilder newBuilder(final TypeReference target) { return newBuilder(target.getType()); } /** * Will create a newInstance of JdbcMapperBuilder on the specified type. * @param target the type * @param the jdbcMapper target type * @return the builder */ public JdbcMapperBuilder newBuilder(final Type target) { ClassMeta classMeta = getClassMeta(target); return newBuilder(classMeta); } public JdbcMapperBuilder newBuilder(ClassMeta classMeta) { MapperConfig mapperConfig = mapperConfig(classMeta.getType()); return new JdbcMapperBuilder( classMeta, mapperConfig, getterFactory, new JdbcMappingContextFactoryBuilder(!mapperConfig.unorderedJoin())); } /** * * @param target the type * @param the type * @return a builder to create a mapper from target to PreparedStatement */ public PreparedStatementMapperBuilder buildFrom(final Class target) { return buildFrom((Type) target); } public PreparedStatementMapperBuilder buildFrom(final Type target) { ClassMeta classMeta = getClassMeta(target); return buildFrom(classMeta); } public PreparedStatementMapperBuilder buildFrom(final TypeReference target) { return buildFrom(target.getType()); } public PreparedStatementMapperBuilder buildFrom(final ClassMeta classMeta) { return new PreparedStatementMapperBuilder(classMeta, mapperConfig(classMeta.getType()), ConstantTargetFieldMapperFactoryImpl.newInstance(PreparedStatementSetterFactory.INSTANCE, PreparedStatement.class)); } public PreparedStatementMapperBuilder from(final Class target) { return buildFrom(target); } public PreparedStatementMapperBuilder from(final Type target) { return buildFrom(target); } public PreparedStatementMapperBuilder from(final TypeReference target) { return buildFrom(target); } public PreparedStatementMapperBuilder from(final ClassMeta classMeta) { return buildFrom(classMeta); } /** * Will create a DynamicMapper on the specified target class. * @param target the class * @param the jdbcMapper target type * @return the DynamicMapper */ public DynamicJdbcMapper newMapper(final Class target) { return newMapper((Type) target); } /** * Will create a DynamicMapper on the type specified by the TypeReference. * @param target the TypeReference * @param the jdbcMapper target type * @return the DynamicMapper */ public DynamicJdbcMapper newMapper(final TypeReference target) { return newMapper(target.getType()); } public CrudDSL crud(final Type target, final Type keyTarget) { return crud(this.getClassMeta(target), this.getClassMeta(TypeHelper.toBoxedClass(keyTarget))); } public CrudDSL crud(final ClassMeta target, final ClassMeta keyTarget) { return new CrudDSL(target, keyTarget, JdbcMapperFactory.newInstance(this)); } public CrudDSL crud(final Class target, final Class keyTarget) { return crud((Type)target, (Type)keyTarget); } /** * Will create a DynamicMapper on the specified type. * @param target the type * @param the jdbcMapper target type * @return the DynamicMapper */ public DynamicJdbcMapper newMapper(final Type target) { final ClassMeta classMeta = getClassMeta(target); return new DynamicJdbcSetRowMapper(new SetRowMapperFactory(classMeta), new MapperKeyFactory(), new MapperKeyFactory()); } public JdbcSourceFieldMapper newSourceFieldMapper(Type target) { final ClassMeta classMeta = getClassMeta(target); return new DynamicJdbSourceFieldMapper(new SourceFieldMapperFactory(classMeta), new MapperKeyFactory()); } public static class DynamicJdbSourceFieldMapper extends DynamicSourceFieldMapper implements JdbcSourceFieldMapper { public DynamicJdbSourceFieldMapper( UnaryFactory, ContextualSourceFieldMapper> mapperFactory, UnaryFactoryWithException, SQLException> mapperKeyFromRow) { super(mapperFactory, mapperKeyFromRow, JdbcColumnKeyMapperKeyComparator.INSTANCE); } private ContextualSourceFieldMapper getMapper(ResultSetMetaData metaData) throws SQLException { return getMapper(JdbcColumnKey.mapperKey(metaData)); } @Override public String toString() { return "DynamicJdbcSetRowMapper{}"; } @Override public MappingContext newMappingContext(ResultSet resultSet) throws SQLException { JdbcSourceFieldMapper mapper = (JdbcSourceFieldMapper) getMapper(resultSet.getMetaData()); return mapper.newMappingContext(resultSet); } } public static class DynamicJdbcSetRowMapper extends DynamicSetRowMapper implements DynamicJdbcMapper { public DynamicJdbcSetRowMapper( UnaryFactory, SetRowMapper> mapperFactory, UnaryFactoryWithException, SQLException> mapperKeyFromRow, UnaryFactoryWithException, SQLException> mapperKeyFromSet) { super(mapperFactory, mapperKeyFromRow, mapperKeyFromSet, JdbcColumnKeyMapperKeyComparator.INSTANCE); } @Override public JdbcMapper getMapper(ResultSetMetaData metaData) throws SQLException { return (JdbcMapper) getMapper(JdbcColumnKey.mapperKey(metaData)); } @Override public String toString() { return "DynamicJdbcSetRowMapper{}"; } @Override public MappingContext newMappingContext(ResultSet resultSet) throws SQLException { return getMapper(resultSet.getMetaData()).newMappingContext(resultSet); } } /** * Create a discriminator builder based on the specified property * @param column the discriminator property * @param the root type of the jdbcMapper * @return a builder to specify the type mapping */ public DiscriminatorJdbcBuilder newDiscriminator(String column) { ignorePropertyNotFound(); addColumnDefinition(column, FieldMapperColumnDefinition.ignoreDefinition()); return new DiscriminatorJdbcBuilder(column, this); } private static class MapperKeyFactory implements UnaryFactoryWithException, SQLException> { @Override public MapperKey newInstance(ResultSet set) throws SQLException { return JdbcColumnKey.mapperKey(set.getMetaData()); } } private class SetRowMapperFactory implements UnaryFactory, SetRowMapper> { private final ClassMeta classMeta; public SetRowMapperFactory(ClassMeta classMeta) { this.classMeta = classMeta; } @Override public SetRowMapper newInstance(MapperKey jdbcColumnKeyMapperKey) { final JdbcMapperBuilder builder = newBuilder(classMeta); for(JdbcColumnKey key : jdbcColumnKeyMapperKey.getColumns()) { builder.addMapping(key); } return builder.mapper(); } } private class SourceFieldMapperFactory implements UnaryFactory, ContextualSourceFieldMapper> { private final ClassMeta classMeta; public SourceFieldMapperFactory(ClassMeta classMeta) { this.classMeta = classMeta; } @Override public ContextualSourceFieldMapper newInstance(MapperKey jdbcColumnKeyMapperKey) { final JdbcMapperBuilder builder = newBuilder(classMeta); for(JdbcColumnKey key : jdbcColumnKeyMapperKey.getColumns()) { builder.addMapping(key); } return builder.newSourceFieldMapper(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy