Earlier quoted context omitted.
Another great option in Java is jOOQ, which lets you write type-safe and potentially composable queries such as: context .update(User.USER) .set(User.USER.NAME, userName) .where(User.USER.ID.eq(userId)) .execute()
jOOQ and its DSL is good, however IMO it's more readable using raw SQL (by using `context.fetchInto` and its variants) than to using DSL when deal with complex query.
For small queries with straight forward joins, a query builder is nice and readable.
But for larger, more complex queries, I found putting the query into its own file was best for readability.