Using JooqTemplate requires no code generation and no XML configuration.
Add Dependency
gradle:
implementation 'net.sf.sprtool:sprtool-jooq:1.7.0' maven:
<dependency> <groupId>net.sf.sprtool</groupId> <artifactId>sprtool-jooq</artifactId> <version>1.7.0</version> </dependency> Inject JooqTemplate
import static net.sf.sprtool.jooq.JooqFields.*; import net.sf.sprtool.jooq.JooqTemplate; @Autowired private JooqTemplate jt; Using JooqTemplate
Method 1: conditions() — Field-Value Pair Varargs (Recommended)
conditions(Object... fieldValuePairs) takes arguments in pairs of "field name, value"; the operator is written directly after the field name string, and when no operator is written the default is ==. It returns a List<Condition>, and conditions whose values are null are automatically ignored:
// name = 'Smartphone' and price > 1000 and status = 'on_sale' List<Condition> conds = jt.conditions( "name", "Smartphone", "price>", 1000, // the > operator follows the field name "stock<=", 50, // the <= operator "status", "on_sale"); // default operator == // You can also separate the field and operator with a colon: "price:>" List<Condition> conds2 = jt.conditions("price:>", 1000); When a parameter value is null, that condition is ignored — ideal for dynamic queries: if the frontend doesn't send a value, no filter is applied:
// When nameParam is null, no name condition is generated List<Condition> conds = jt.conditions("name", nameParam, "category", categoryParam); You can also mix native jOOQ Condition objects directly into the varargs:
Condition other = DSL.field("price").ge(1000); List<Condition> conds = jt.conditions("category", "Electronics", other); Method 2: and() / or() — Directly Returning a Single Combined Condition
and(...) and or(...) take arguments exactly like conditions(); the difference is the return value: multiple conditions are merged with AND / OR into a single Condition, and null is returned when there are no conditions at all:
// AND: name = 'John' and age > 30 and status = 'active' Condition cond = jt.and("name", "John", "age>", 30, "status", "active"); // OR: name like 'Soph%' or name like 'Fra%' Condition cond2 = jt.or("name:%l", "Soph", "name:%l", "Fra"); // Empty arguments return null Condition empty = jt.and(); // null Find two users with OR (corresponding to the user_table example in JooqTemplateOrTest):
// name = 'John' or name = 'Lee' Condition cond = jt.or("name", "John", "name", "Lee"); List<LowerCaseRecord> records = jt.queryLowerCaseRecord("user_table", cond); Method 3: condition() — Single-Condition Method
condition(Name fieldName, String operator, Object[] values) accepts a jOOQ Name, an operator string, and a value array, and generates a single Condition. The number of values must match what the operator requires, otherwise an IllegalArgumentException is thrown:
import org.jooq.Condition; import org.jooq.Name; import org.jooq.impl.DSL; // Equality: == requires 1 value Condition c1 = jt.condition(DSL.name("name"), "==", new Object[]{"Smartphone"}); // Comparison: > requires 1 value Condition c2 = jt.condition(DSL.name("price"), ">", new Object[]{1000}); // in: requires 1 value, and the value must be a Collection or Object[] Condition c3 = jt.condition(DSL.name("category"), "in", new Object[]{Arrays.asList("Electronics", "Appliances", "Apparel")}); // between: requires 2 values Condition c4 = jt.condition(DSL.name("created_at"), "between", new Object[]{beginDate, endDate}); // isnull: requires 0 values Condition c5 = jt.condition(DSL.name("remark"), "isnull", new Object[]{}); This method also follows the null rules: a null value returns null (ignored); wrapping with ND(null) generates is null; a null field name or operator returns null; an invalid operator throws IllegalArgumentException:
// Value is null → returns null, condition ignored Condition c = jt.condition(DSL.name("name"), "==", new Object[]{null}); // null // ND wrapping null → generates name is null Condition c2 = jt.condition(DSL.name("name"), "==", new Object[]{ND(null)}); // Value count mismatch → throws IllegalArgumentException("Operator require value count is 1") Condition c3 = jt.condition(DSL.name("name"), "==", new Object[]{}); not() — Negating a Condition
not(Condition) negates an existing condition and returns null when the input is null:
Condition original = jt.and("status", "disabled"); Condition notDisabled = jt.not(original); // not (status = 'disabled') orOne() — Multiple Fields Matching the Same Value
orOne(Object... sameOneValues) starts with several "fields" (single-value operators), and the last argument is the shared value, generating field1 op value or field2 op value .... A typical "global keyword search" scenario:
// name = 'Apple' or nick_name = 'Apple' or remark = 'Apple' Condition cond = jt.orOne("name", "nick_name", "remark", "Apple"); Null Fallback for between
between / notbetween take 2 values; when either end is null, it automatically falls back to a one-sided comparison, and when both ends are null the whole condition is ignored:
// Both begin and end are non-null: price between 100 and 500 jt.conditions("price:between", 100, 500); // begin=100, end=null: price >= 100 jt.conditions("price:between", 100, null); // notbetween fallback: begin=null, end=500 → price > 500 jt.conditions("price:notbetween", null, 500); Operator Reference
Condition operators (written after the field name or passed to condition(); all are case-insensitive):
| Operator | Value Count | Meaning |
|---|---|---|
== (default) | 1 | Equal to |
<> | 1 | Not equal to |
> >= < <= | 1 | Comparison |
% / like | 1 | Contains %value% |
%l / llike | 1 | Prefix match value% |
%r / rlike | 1 | Suffix match %value |
in / notin | 1 | Value is a Collection or Object[] |
between / notbetween | 2 | Range; a null end falls back automatically |
isnull / isnotnull | 0 | Null check |
Sort operators (only used in the order part of a query or in orders()): asc, ascnf (nulls first), ascnl (nulls last), desc, descnf, descnl.
Null handling rules:
- In queries (
conditions()/and()/or()/condition()), anullvalue → the condition is ignored. - A value wrapped with
ND(null)→ generatesfield is null. - In
UPDATE/DELETE, anullvalue → generatesfield is null.
