Why Not BeanPropertyRowMapper?

First, the performance of BeanPropertyRowMapper is abysmal, as it says in the doc it’s not made for that. This module offers performance very close to a manually written RowMapper - it could even be faster as name access to a column is more expensive than by index.

Second SimpleFlatMapper support constructor injection, factory method, deep object etc…

Third, it also supports SqlParameterSource, and Crud operations.

You might also have a look at Spring-JDBC-ROMA that also creates RowMapper.

Also sfm supports one-to-many mapping using the ResultSetExtractor or the PreparedStatementCallback.

Getting Started Spring jdbc

Maven Central JavaDoc

Setting up the environment

Add the Dependency to your build.

for Maven:

Java 8, 9, 10 , 11 no module-info

<dependency>
    <groupId>org.simpleflatmapper</groupId>
    <artifactId>sfm-springjdbc</artifactId>
    <version>6.0.11</version>
</dependency>

Java 6, 7

<dependency>
    <groupId>org.simpleflatmapper</groupId>
    <artifactId>sfm-springjdbc</artifactId>
    <version>6.0.11</version>
    <classifier>jdk16</classifier>
</dependency>

Java 9, 10 , 11 with module-info

<dependency>
    <groupId>org.simpleflatmapper</groupId>
    <artifactId>sfm-springjdbc</artifactId>
    <version>6.0.11</version>
    <classifier>jdk9</classifier>
</dependency>

RowMapper

class MyDao {
    private final RowMapper<DbObject> rowMapper =
        JdbcTemplateMapperFactory.newInstance().newRowMapper(DbObject.class);
        
    public List<DbObject> findAll() {
        return template.query(DbHelper.TEST_DB_OBJECT_QUERY, rowMapper);
    }
}

SqlParameterSource

class MyDao {
    private final SqlParameterSourceFactory<DbObject> parameterSourceFactory =
        JdbcTemplateMapperFactory
            .newInstance()
            .newSqlParameterSourceFactory(DbObject.class);

    public void insertObject(DbObject object) {
        template.update(
            "INSERT INTO DBOBJECTS(id, name, email)"
            + " VALUES(:id, :name, :email)",
            parameterSourceFactory.newSqlParameterSource(object));

    }

    public void insertObjects(Collection<DbObject> objects) {
        template.batchUpdate(
            "INSERT INTO DBOBJECTS(id, name, email)"
            + "VALUES(:id, :name, :email)",
            parameterSourceFactory.newSqlParameterSources(objects));
    }
}

java.sql.Types

Because the parameter source does not have any metadata, the java.sql.Types will be extrapolated from the object property type. If the sql type implied is not the one desired, you can specify one manually by adding a SqlTypeColumnProperty.

For example when using a non jdbc 4.2 compliant driver with a ZonedDateTime. Sfm will use a TIMESTAMP_WITH_TIMEZONE which may is not supported by the driver. The following code will override the type with Types.TIMESTAMP :

class MyDao {
    private final SqlParameterSourceFactory<DbObject> parameterSourceFactory =
        JdbcTemplateMapperFactory
            .newInstance()
            .addColumnProperty("timestamp", SqlTypeColumnProperty.of(Types.TIMESTAMP))
            .newSqlParameterSourceFactory(DbObject.class);
}

Just make sure that you are using the column name not the property name.

Crud

class MyDao {

    JdbcTemplateCrud<DbObject, Long> objectCrud;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        objectCrud =
            JdbcTemplateMapperFactory
                .newInstance()
                .<DbObject, Long>crud(DbObject.class, Long.class)
                .to(template, "TEST_DB_OBJECT");
    }

    public void insertObject(DbObject object) {
        crud.create(object);
    }

    public void insertObjects(Collection<DbObject> objects) {
        crud.create(objects);
    }
}

More examples

See JdbcTemplateMapperFactoryTest for more examples.