Provides a jOOQ custom type binding
for the jOOQ code generator to interpret PostgreSQL json
and jsonb
fields, either simply as String
or as
specific Json
and Jsonb
types, allowing use of JsonDSL
and JsonbDSL
classes to use
PostgreSQL JSON functions with jOOQ code.
Requires at least Java 8.
- Include as a Maven dependency
- Configure the jOOQ code generator
- Using in code
- PostgreSQL json operator support
- Example
- References
First, add the following Maven dependency:
<dependency>
<groupId>com.github.t9t.jooq</groupId>
<artifactId>jooq-postgresql-json</artifactId>
<version>0.3.0</version>
</dependency>
Then, configure the code generator like this:
<database>
<forcedTypes>
<!-- When you just want json/jsonb fields mapped as String: -->
<forcedType>
<userType>java.lang.String</userType>
<binding>com.github.t9t.jooq.json.JsonStringBinding</binding>
<types>json</types>
</forcedType>
<forcedType>
<userType>java.lang.String</userType>
<binding>com.github.t9t.jooq.json.JsonbStringBinding</binding>
<types>jsonb</types>
</forcedType>
<!-- When you want to map json/jsonb fields to specialized Json/Jsonb types: -->
<forcedType>
<userType>com.github.t9t.jooq.json.Json</userType>
<binding>com.github.t9t.jooq.json.JsonBinding</binding>
<types>json</types>
</forcedType>
<forcedType>
<userType>com.github.t9t.jooq.json.Jsonb</userType>
<binding>com.github.t9t.jooq.json.JsonbBinding</binding>
<types>jsonb</types>
</forcedType>
</forcedTypes>
</database>
The first example above will use a Java type of String
for all json
and jsonb
fields, and will use the
JsonStringBinding
and JsonbStringBinding
respectively to convert the fields.
The second example instead binds json
fields to Json
using JsonBinding
, and jsonb
fields to Jsonb
using
JsonbBinding
. This enables the use of JsonDSL
and JsonbDSL
.
If you want to only configure it for certain specific fields, add an <expression>
element to the <forcedType>
element, for example:
<expression>.*json.*</expression>
Or:
<expression>site\.users\.profile</expression>
The expression
element contains a regular expression. The first example matches any field which contains the word
"json" in its name while the second matches exactly the profile
field in the users
table in the site
schema. See
the jOOQ documentation for more information.
By default the jOOQ code generator will generate Object
as a return value for json fields and return the raw
PostgreSQL driver's JDBC type, PGobject
. It's up to the user to interpret this somehow. Using this binding, jOOQ
will instead just return the json data as String
, Json
, or Jsonb
.
An example before using this binding when doing a select
query:
public String fetchData(long id) {
Record1<Object> r = dsl.select(MY_TABLE.DATA)
.from(MY_TABLE)
.where(MY_TABLE.ID.eq(id))
.fetchOne();
Object o = r.value1();
String s = ((PGobject) o).getValue();
return s;
}
When using this binding, instead it can be simplified to:
public String fetchData(long id) {
Record1<String> r = dsl.select(MY_TABLE.DATA)
.from(MY_TABLE)
.where(MY_TABLE.ID.eq(id))
.fetchOne();
String s = r.value1();
return s;
}
Or, in the case of Json
and Jsonb
:
public String fetchData(long id) {
Record1<Jsonb> r = dsl.select(MY_TABLE.DATA)
.from(MY_TABLE)
.where(MY_TABLE.ID.eq(id))
.fetchOne();
Jsonb j = r.value1();
return j == null ? null : j.getValue();
}
Reference: https://www.postgresql.org/docs/11/functions-json.html
Operators available for both json
(through JsonDSL
) and jsonb
(through JsonbDSL
):
Op | Operand | Description | Method |
---|---|---|---|
-> |
int |
Get array element | arrayElement() |
-> |
text |
Get object field | fieldByKey() |
->> |
int |
Get array element as text | arrayElementText() |
->> |
text |
Get object field as text | fieldByKeyText() |
#> |
text[] |
Get object at path | objectAtPath() |
#>> |
text[] |
Get object at path as text | objectAtPathText() |
Operators available only for jsonb
(through JsonbDSL
):
Op | Operand | Description | Method |
---|---|---|---|
@> |
jsonb |
Does contain value? | contains() |
<@ |
jsonb |
Are entries contained? | containedIn() |
? |
text |
Does the key exist? | hasKey() |
?| |
text[] |
Does any key exist? | hasAnyKey() |
?& |
text[] |
Do all keys exist? | hasAllKeys() |
|| |
jsonb |
Concatenate values | concat() |
- |
text |
Delete key or element | delete() |
- |
text[] |
Delete multiple keys or elements | delete() |
- |
int |
Delete array element | deleteElement() |
#- |
text[] |
Delete field for path | deletePath() |
See the integration-tests module's pom.xml for an example of the
jooq-codegen
Maven plugin with the custom json bindings.
For some code usage examples, refer to:
String
: integration-tests/.../JsonStringBindingITJson
/Jsonb
: integration-tests/.../JsonBindingIT