A jOOQ-CodeGenerator to create vertx-ified DAOs and POJOs!
Perform all CRUD-operations asynchronously and convert your POJOs from/into a io.vertx.core.json.JsonObject using the API and
driver of your choice.
Fast, faster, reactive.
- Starting from this version on,
vertx-jooqadds support for this winning, high performance postgres driver. - Finally added support for
DAO#insertReturningfor the async postgres driver. - A new
UnifiedQueryExecutorinterface that allows the execution of arbitrary jOOQ-SQL against an API with the same return value for all drivers! Currently there are three interfaces you can use:ClassicQueryExecutor,CompletableFutureQueryExecutorandRXQueryExecutor. The following is possible now:
//first, you decide to use the classic API using JDBC
ClassicQueryExecutor queryExecutor = new JDBCClassicGenericQueryExecutor(configuration,vertx);
Future<QueryResult> queryResult = queryExecutor.query(dslContext ->
dslContext
.selectFrom(Tables.SOMETHING)
.where(Tables.SOMETHING.SOMEID.eq(something.getSomeid()))
);
//fetching values using new QueryResult-API
queryResult.map(res -> {
Integer someId = res.get(Tables.SOMETHING.SOMEID);
return someId;
});
...
//now some time in the future you decide to use the reactive driver instead
ClassicQueryExecutor queryExecutor = new ReactiveClassicGenericQueryExecutor(configuration,pgClient);
//the return value for the query didn't change!
Future<QueryResult> queryResult = queryExecutor.query(dslContext ->
dslContext
.selectFrom(Tables.SOMETHING)
.where(Tables.SOMETHING.SOMEID.eq(something.getSomeid()))
);
queryResult.map(res -> {
Integer someId = res.get(Tables.SOMETHING.SOMEID);
//hooray same API
return someId;
});
- In addition you can now obtain the
QueryExecutorfrom every DAO by callingDAO.queryExecutor(). - Move away from
GeneratorStrategiesto generate DAOs: it was a misconception to useGeneratorStrategiesto distinguish between the APIs, drivers and injection-support. Instead, there is now a Builder-API to create theVertxGeneratorof your choice. This comes in handy if you configure your jOOQ code generator programmatically. Example:
VertxGenerator vertxGenerator = VertxGeneratorBuilder
.init()
.withClassicAPI()
.withAsyncDriver()
.withGuice(true)
.build();
- Breaking changes:
- DAOs are no longer aware of
org.jooq.Configuration, instead it is now located in theQueryExecutor. QueryExecutorAPI changed in a way, that all methods no longer accept instances oforg.jooq.QuerybutFunction<DSLContext, ? extends ResultQuery<R>>. It is no longer necessary to keep aConfigurationobject in order to execute random jOOQ SQL.JDBCQueryExecutor.executewas renamed toJDBCQueryExecutor.executeAny.- Upgrade from 3.x: first, change the generator- and strategy name in your code generator configuration.
Use the names as described in the module's documentation of the API and driver of your choice (e.g.
vertx-jooq-classic-async). If you've used ownGeneratorStrategiesall have to extend now fromVertxGeneratorStrategy. Then, update the dependencies to the code-generator and generate the code. Now you should update the vertx-jooq-YOUR_API-YOUR_DRIVER dependency. In case you've been usingQueryExecutorsyou'll have to change the method calls to it as described above.
- DAOs are no longer aware of
Before you start generating code using vertx-jooq, you have to answer these questions:
- What API do you want to use? There are three options:
- a
io.vertx.core.Future-based API. This isvertx-jooq-classic. - a rxjava2 based API. This is
vertx-jooq-rx. - an API that returns a vertx-ified implementation
of
java.util.concurrent.CompletableFuturefor all async DAO operations. This isvertx-jooq-completablefuture.
- a
- How do you want to communicate with the database? There are two options:
- Using good old JDBC, check for the modules with
-jdbcsuffix. - Using this asynchronous database driver, check for
-asyncmodules. - Using this reactive postgres database driver, check for
-reactivemodules.
- Using good old JDBC, check for the modules with
- Do you use Guice for dependency injection?
When you made your choice, you can start to configure the code-generator. This can be either done programmatically or using a maven- / gradle-plugin (recommended way). Please check the documentation in the module of the API of your choice how to set it up:
vertx-jooq-classic-asyncvertx-jooq-classic-jdbcvertx-jooq-classic-reactivevertx-jooq-rx-asyncvertx-jooq-rx-jdbcvertx-jooq-rx-reactivevertx-jooq-completablefuture-asyncvertx-jooq-completablefuture-jdbcvertx-jooq-completablefuture-reactive
Once the generator is set up, it will create DAOs like in the code snippet below (classic-API, JDBC, no dependency injection):
//Setup your jOOQ configuration
Configuration configuration = ...
//setup Vertx
Vertx vertx = Vertx.vertx();
//instantiate a DAO (which is generated for you)
SomethingDao dao = new SomethingDao(configuration,vertx);
//fetch something with ID 123...
dao.findOneById(123)
.setHandler(res->{
if(res.succeeded()){
vertx.eventBus().send("sendSomething", res.result().toJson())
}else{
System.err.println("Something failed badly: "+res.cause().getMessage());
}
});
//maybe consume it in another verticle
vertx.eventBus().<JsonObject>consumer("sendSomething", jsonEvent->{
JsonObject message = jsonEvent.body();
//Convert it back into a POJO...
Something something = new Something(message);
//... change some values
something.setSomeregularnumber(456);
//... and update it into the DB
Future<Integer> updatedFuture = dao.update(something);
});
//or do you prefer writing your own type-safe SQL? Use the QueryExecutor from the DAO...
ClassicQueryExecutor queryExecutor = dao.queryExecutor();
//... or create a new one when there is no DAO around :)
queryExecutor = new JDBCClassicGenericQueryExecutor(configuration,vertx);
Future<Integer> updatedCustom = queryExecutor.execute(dslContext ->
dslContext
.update(Tables.SOMETHING)
.set(Tables.SOMETHING.SOMEREGULARNUMBER,456)
.where(Tables.SOMETHING.SOMEID.eq(something.getSomeid()))
.execute()
);
//check for completion
updatedCustom.setHandler(res->{
if(res.succeeded()){
System.out.println("Rows updated: "+res.result());
}else{
System.err.println("Something failed badly: "+res.cause().getMessage());
}
});
The generator will omit datatypes that it does not know, e.g. java.sql.Timestamp. To fix this, you can subclass the generator, handle these types and generate the code using your generator.
See the handleCustomTypeFromJson and handleCustomTypeToJson methods in the AbstractVertxGenerator or checkout the CustomVertxGenerator
from the tests.
This library comes without any warranty - just take it or leave it. Also, the author is neither connected to the company behind vertx nor the one behind jOOQ.