Skip to content
Ravi Chodavarapu edited this page Mar 7, 2017 · 5 revisions

datamill has a DatabaseClient for doing SQL queries - it has an API for building queries in Java (note the usage of the reflection utilities described in Reflection):

DatabaseClient client = new DatabaseClient("jdbc:mysql://localhost:3306/db", "user", "pass123");
client.selectAllIn(outline)
    .from(outline)
    .where(c -> c.eq(outline.member(m -> m.getUserName()), userName))
    .all()
    .getAs(r -> outline.wrap(new User())
        .set(m -> m.getId(), r.column(outline.member(m -> m.getId())))
        .set(m -> m.getUserName(), r.column(outline.member(m -> m.getUserName())))
        .set(m -> m.getEmail(), r.column(outline.member(m -> m.getEmail())))
        .set(m -> m.getPassword(), r.column(outline.member(m -> m.getPassword())))
        .unwrap()));

As you can see, when you execute queries with the DatabaseClient, it returns Observables so that you can easily transform the results, and return them as responses in your HTTP response handlers.

Because of the common pattern of using the DatabaseClient together with the OutlineBuilder, a base foundation.stack.datamill.db.Repository class is available to use as a base class for your DAOs - it has an executeQuery method that it will hand to a callback you provide for constructing your query:

public class UserRepository extends Repository<User> {
    public UserRepository(DatabaseClient databaseClient, OutlineBuilder outlineBuilder) {
        super(databaseClient, outlineBuilder, User.class);
    }

    public Observable<User> addUser(User user) {
        return executeQuery(
                (client, outline) ->
                        client.insertInto(outline).row(
                                b -> b.put(outline.member(m -> m.getUserName()), user.getUserName())
                                        .put(outline.member(m -> m.getEmail()), user.getEmail())
                                        .put(outline.member(m -> m.getPassword()), user.getPassword())
                                        .build()))
                .getIds()
                .doOnNext(id -> user.setId(id))
                .map(id -> user);
    }

    public Observable<User> getByUserName(String userName) {
        return executeQuery(
                (client, outline) ->
                        client.selectAllIn(outline)
                                .from(outline)
                                .where(c -> c.eq(outline.member(m -> m.getUserName()), userName))
                                .all()
                                .firstAs(r -> outline.wrap(new User())
                                        .set(m -> m.getId(), r.column(outline.member(m -> m.getId())))
                                        .set(m -> m.getUserName(), r.column(outline.member(m -> m.getUserName())))
                                        .set(m -> m.getEmail(), r.column(outline.member(m -> m.getEmail())))
                                        .set(m -> m.getPassword(), r.column(outline.member(m -> m.getPassword())))
                                        .unwrap()));
    }
...
}

Note: Right now, we only support MySQL! Other databases may work with the queries that are generated but we haven't tested it.

The SQL support is built on the excellent https://github.com/davidmoten/rxjava-jdbc

Clone this wiki locally