7.6.1. The jOOQ DSL
jOOQ comes with its own DSL (for Domain Specific Language) that emulates SQL in Java. It allows you to write SQL statements almost as though Java actually supported them. Its effect is similar to what .NET in C# does with LINQ to SQL.
jOOQ uses an informal BNF notation modelling a unified SQL dialect suitable for most database engines. Unlike other, simpler frameworks that use the Fluent API or the chain method, the jOOQ-based BNF interface does not permit bad query syntax.
A simple SQL query:
SELECT *FROM author aJOIN book b ON a.id = b.author_idWHERE a.year_of_birth > 1920AND a.first_name = 'Paulo'ORDER BY b.title
In jOOQ it looks like this:
Result<Record> result =dsl.select().from(AUTHOR.as("a")).join(BOOK.as("b")).on(a.ID.equal(b.AUTHOR_ID)).where(a.YEAR_OF_BIRTH.greaterThan(1920).and(a.FIRST_NAME.equal("Paulo"))).orderBy(b.TITLE).fetch();
The AUTHOR and BOOK classes describing the corresponding tables must be generated beforehand. The process of generating jOOQ classes according to the specified database schema was described earlier.
We specified table aliases for the AUTHOR and BOOK tables using the AS clause. Here is the same query in DSL without aliases:
Result<Record> result =dsl.select().from(AUTHOR).join(BOOK).on(AUTHOR.ID.equal(BOOK.AUTHOR_ID)).where(AUTHOR.YEAR_OF_BIRTH.greaterThan(1920).and(AUTHOR.FIRST_NAME.equal("Paulo"))).orderBy(BOOK.TITLE).fetch();
Now we take a more complex query with aggregate functions and grouping:
SELECT AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, COUNT(*)FROM AUTHORJOIN BOOK ON AUTHOR.ID = BOOK.AUTHOR_IDWHERE BOOK.LANGUAGE = 'DE'AND BOOK.PUBLISHED > '2008-01-01'GROUP BY AUTHOR.FIRST_NAME, AUTHOR.LAST_NAMEHAVING COUNT(*) > 5ORDER BY AUTHOR.LAST_NAME ASC NULLS FIRSTOFFSET 1 ROWSFETCH FIRST 2 ROWS ONLY
In jOOQ:
dsl.select(AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, count()).from(AUTHOR).join(BOOK).on(BOOK.AUTHOR_ID.equal(AUTHOR.ID)).where(BOOK.LANGUAGE.equal("DE")).and(BOOK.PUBLISHED.greaterThan("2008-01-01")).groupBy(AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME).having(count().greaterThan(5)).orderBy(AUTHOR.LAST_NAME.asc().nullsFirst()).limit(2).offset(1).fetch();
‘Dialect’ in the jOOQ context represents not just the SQL dialect of the database but also the major version number of the database engine. The field ‘limit’, limiting the number of records returned, will be generated according to the SQL syntax available to the database engine. The example above used |
You can build a query in parts. This will allow you to change it dynamically, to change the sort order or to add additional filter conditions.
SelectFinalStep<?> select= dsl.select().from(PRODUCT);SelectQuery<?> query = select.getQuery();switch (searchOper) {case "eq":query.addConditions(PRODUCT.NAME.eq(searchString));break;case "bw":query.addConditions(PRODUCT.NAME.startsWith(searchString));break;case "cn":query.addConditions(PRODUCT.NAME.contains(searchString));break;}switch (sOrd) {case "asc":query.addOrderBy(PRODUCT.NAME.asc());break;case "desc":query.addOrderBy(PRODUCT.NAME.desc());break;}return query.fetchMaps();
