Reduce your boiler-plate code with SimpleFlatMapper

About me

 

No time for that sh*t, it's lightning talk!

 

Scuse me French.

@arnaudroger http://simpleflatmapper.org

SimpleFlatMapper

 

What ?

Maps flat structure

  • CSV
  • Jdbc ResultSet
  • HSSFSheet
  • jOOQ Record
  • Datastax ResultSet
  • ...

To POJOs with no configuration needed,

and no use of Unsafe and setAccessible.

No boxing either, no external dependencies.

@arnaudroger http://simpleflatmapper.org

SimpleFlatMapper

 

Inject via:

  • Constructor
  • Setter, everybody can do that.
  • Field if public and non final.
  • Factory method
  • Builders
  • Value type
  • Inner Object

@arnaudroger http://simpleflatmapper.org

SimpleFlatMapper

 

But is it fast?

 

Yes super fast,

  • generate bytecode using ASM*
  • no boxing
  • JIT can inline the cr*p out of it

 

* Unfortunatly due to the complexity of OSGI ClassLoader lifecycle ASM generation is disable when running in an OSGI container

PS : reflection call is not slow, lookup is.

@arnaudroger http://simpleflatmapper.org

SimpleFlatMapper

 

Less bullsh*t more code

let's look at JdbcTemplate example here.

 

@arnaudroger http://simpleflatmapper.org

The schema

 

 

 

@arnaudroger http://simpleflatmapper.org

The data

 

@arnaudroger http://simpleflatmapper.org

The data

 

So that query

Returns

@arnaudroger http://simpleflatmapper.org

Simple select

SELECT firstname, lastname
FROM users
Manual RowMapper

 

RowMapper<User> rm = 
    (rs, i) -> new User(
                  rs.getString("firstname"),   
                  rs.getString("lastname"));

 

So far so good,

but only work when those 2 columns are present.

@arnaudroger http://simpleflatmapper.org

Simple select


Why not use BeanPropertyRowMapper?


as per javadoc

Please note that this class is designed to provide convenience rather than high performance. For best performance, consider using a custom RowMapper implementation.

It is the slowest mapper on the planet... don't use it.



@arnaudroger http://simpleflatmapper.org

Simple select - SFM

 

 

SFM RowMapper

  RowMapper<User> rm =
    JdbcTemplateMapperFactory
        .newInstance()
        .newRowMapper(User.class);

 

  • adaptive, will map any column from the rs
  • faster because it uses index lookup

Not convinced? I get you... next lets look at ....

 

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

@arnaudroger http://simpleflatmapper.org

one-to-many?

 

 

 

  • Not possible with RowMapper.
  • Need ResultSetExtractor + RowMapper

 

 

 

@arnaudroger http://simpleflatmapper.org

one-to-many?

ResultSetExtractor + RowMapper

RowMapper<User> userRowMapper =
        (rs, i) ->
                new User(
                        rs.getInt("id"),
                        rs.getString("firstname"),
                        rs.getString("lastname"));

ResultSetExtractor<List<User>> rse = rs -> {
    List<User> users = new ArrayList<>();
    User currentUser = null;
    while (rs.next()) {
        int id = rs.getInt("id");
        if (currentUser == null) { // initial object
            currentUser = userRowMapper.mapRow(rs, 0);
        } else if (currentUser.getId() != id) { // break
            users.add(currentUser);
            currentUser = userRowMapper.mapRow(rs, 0);
        }
        currentUser.getRoles().add(rs.getString("roles_name"));
    }
    if (currentUser != null) { // last object
        users.add(currentUser);
    }
    return users;
};

 

@arnaudroger http://simpleflatmapper.org

one-to-many?

With SFM

ResultSetExtractor<List<User>> rse = 
        JdbcTemplateMapperFactory
                .newInstance()
                .addKeys("id")
                .newResultSetExtractor(User.class);

 

Is that it?

can I have more joins?

see https://arnaudroger.github.io/blog/2017/03/02/jooq-one-to-many-without-dto.html

with example of mapping to

Tuple2<AuthorRecord,List<Tuple2<BookRecord,List<BookToBookStoreRecord>>>

@arnaudroger http://simpleflatmapper.org

Crud operation you ask?

JdbcTemplateCrud<User, Long> objectCrud =
      JdbcTemplateMapperFactory.newInstance()
            .crud(User.class, Integer.class)
            .to(template, "users");

I can Create

objectCrud.create(user);

Read

objectCrud.read(2)

Update

objectCrud.update(user);

Delete

objectCrud.delete(2);

I have also batch insert - and upsert for postgres/mysql -

objectCrud.create(Arrays.asList(user1, user2));
objectCrud.createOrUpdate(Arrays.asList(user1, user2));

@arnaudroger http://simpleflatmapper.org

Fastest csv parser

Really ? are you using opencsv? supercsv drop that. the only ones worth considering are

  •  jackson-csv
  •  univocity - only for big file
  •  sfm-csv

 

 

 

 

 

@arnaudroger http://simpleflatmapper.org

Fastest csv parser

Benchmark time to parse a 3+ million rows csv

see http://simpleflatmapper.org/12-csv-performance.html

 

 

 

 

 

@arnaudroger http://simpleflatmapper.org

Mapping from a csv?

 

easy as that

try (Iterator<User> it = 
        CsvParser.mapTo(User.class).addKey("id").iterator(myFile)) {
   while(it.hasNext()) {
      User u = it.next();
   }
}

 

 

 

PS: we currently only support

one join in a csv file. there is a

ticket for that

 

@arnaudroger http://simpleflatmapper.org

What else can it do?

  • Type conversion

  • Native UUID support

  • java time support

  • jOOL tuple support

  • Immutables, Lombok support

  • can map complex type like

    • Tuple2<User, List<String>>

  • Work on java 6, 7, 8 and 9!

  • as of recently supports protobuf object

 

 

 

@arnaudroger http://simpleflatmapper.org

Can you support a new flat structure?

 

Pretty easily, look at the code needed for jOOQ

https://github.com/arnaudroger/SimpleFlatMapper/tree/master/sfm-jooq/src/main/java/org/simpleflatmapper/jooq

Most of the work is done in sfm-map.

  • Column key
  • GetterFactory for map from
  • SetterFactory for map to
  • Some plumbing

 

 

 

@arnaudroger http://simpleflatmapper.org

Just give it a try.

 

it's MIT License, and get a few thousands download a month.

 

If you have any problem just raise an issue, or send an email on the empty google group.

 

http://simpleflatmapper.org

 

 

 

@arnaudroger http://simpleflatmapper.org

Questions?

@arnaudroger http://simpleflatmapper.org

nidevconf-sfm

By Arnaud Roger