When browsing Hacker News, I recently stumbled upon Benji Weber’s most interesting attempt at creating typesafe database interaction with Java 8. Benji created a typesafe query DSL somewhat similar to jOOQ with the important difference that it uses Java 8 method references to introspect POJOs and deduce query elements from it. This is best explained by example:
Optional<Person> person = from(Person.class) .where(Person::getFirstName) .like("%ji") .and(Person::getLastName) .equalTo("weber") .select( personMapper, connectionFactory::openConnection);
The above query can then be transformed into the following SQL statement:
SELECT * FROM person WHERE first_name LIKE ? AND last_name = ?
This is indeed a very interesting approach, and we’ve seen similar ideas around, before. Most prominently, such ideas were implemented in:
- JaQu, another very interesting competitor product of jOOQ, created by Thomas Müller, the maintainer of the popular H2 database
- LambdaJ, an attempt to bring lambda expressions to Java long before Java 8
- OhmDB, a new NoSQL data store with a fluent query DSL
What’s new in Benji’s approach is really the fact that Java 8 method references can be used instead of resorting to CGLIB and other sorts of bytecode trickery through instrumentation. An example of such trickery is JaQu’s experimental bytecode introspection to transform complex Java boolean expressions into SQL – called “natural syntax”:
Timestamp ts = Timestamp.valueOf("2005-05-05 05:05:05"); Time t = Time.valueOf("23:23:23"); long count = db.from(co). where(new Filter() { public boolean where() { return co.id == x && co.name.equals(name) && co.value == new BigDecimal("1") && co.amount == 1L && co.birthday.before(new Date()) && co.created.before(ts) && co.time.before(t); } }).selectCount();
While these ideas are certainly very interesting to play around with, we doubt such language and bytecode transformations will lead to robust results. People have criticised Hibernate’s use of proxying in various blog posts.
We prefer a WYSIWYG approach where API consumers remain in full control of what is going on. What are your thoughts about such clever ideas?
Filed under: java, sql Tagged: fluent-api, java, magic, Query DSL, sql, trickery
