Data Type Adapters (DTAs)
Data type adapters allow you to extend Iciql’s support for field data types.
For example, you might want to take advantage of the Postgres JSON/JSONB support since 9.3/9.4 but instead of directly handling JSON text documents you might want to represent that JSON as a domain object and serialize/deserialize to JSON only when executing an SQL operation.
Data type adapters give you this flexibility.
NOTE: Data type adapters are reused within a Db instance and are not inherently thread-safe. You must handle thread-safety on your own, if it is an issue.
An example#
Consider the following model class.
@IQTable public class Invoices { @IQColumn(primaryKey = true, autoIncrement = true) public long _id; @IQColumn Date received; @IQColumn @TypeAdapter(InvoiceAdapterImpl.class) Invoice invoice; }
This is a really simple table with three columns, but the third column uses a type adapter to map our invoice object field to an SQL type. You can use the @TypeAdapter
annotation either on the field definition or on the class definition of your domain model.
Let’s take a look at InvoiceAdapterImpl.
public class InvoiceAdapterImpl implements DataTypeAdapter<Invoice> { Mode mode; @Override public void setMode(Mode mode) { this.mode = mode; } @Override public String getDataType() { return "jsonb"; } @Override public Class<Invoice> getJavaType() { return Invoice.class; } Gson gson() { return new GsonBuilder().create(); } @Override public Object serialize(Invoice value) { String json = gson().toJson(value); PGobject pg = new PGobject(); pg.setType(getDataType()); try { pg.setValue(json); } catch (SQLException e) { // ignore, never thrown } return pg; } @Override public Invoice deserialize(Object value) { // the incoming object is always represented as a string final String json = value.toString(); final Invoice invoice = gson().fromJson(json, getJavaType()); return invoice; } }
Here you can see how the InvoiceTypeAdapter defines a Postgres JSONB data type and automatically handles JSON (de)serialization with Google Gson so that the database gets the content in a form that it requires but we can continue to work with objects in Java.
Runtime Mode#
Data type adapters can respond to the Iciql runtime mode (DEV
, TEST
, or PROD
) allowing them to change their behavior. This is useful for targetting a data type that might be available in your production database but may not be available in your development or testing database.
Custom annotations#
It is a little verbose to repeat @TypeAdapter(InvoiceAdapterImpl.class)
everywhere you want to use your adapter.
To simplify this, you can implement your own annotation which specifies your type adapter.
@Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER }) @TypeAdapter(InvoiceAdapterImpl.class) public @interface InvoiceAdapter { }
Included Data Type Adapters#
The following adapters are included in Iciql. They may require an optional dependency such as Gson, XStream, or SnakeYaml.
Common Type Adapters | |||
Adapter | Java | SQL | Description |
com.iciql.adapter.JavaSerializationTypeAdapter | Object | BLOB | Uses Java serialization to (de)serialize your object |
com.iciql.adapter.GsonTypeAdapter<T> | <T> | TEXT | Uses Google Gson to (de)serialize your object as JSON |
com.iciql.adapter.XStreamTypeAdapter | Object | TEXT | Uses XStream to (de)serialize your object as XML |
com.iciql.adapter.SnakeYamlTypeAdapter<T> | <T> | TEXT | Uses SnakeYaml to (de)serialize your object as YAML |
PostgreSQL Type Adapters | |||
Object Adapters | Java | SQL | Description |
com.iciql.adapter.postgresql.JsonObjectAdapter<T> | <T> | JSON | Uses Google Gson to (de)serialize your object as JSON |
com.iciql.adapter.postgresql.JsonbObjectAdapter<T> | <T> | JSONB | Uses Google Gson to (de)serialize your object as JSONB |
com.iciql.adapter.postgresql.XmlObjectAdapter | Object | XML | Uses XStream to (de)serialize your object as XML |
String Adapters | |||
com.iciql.adapter.postgresql.JsonStringAdapter | String | JSON | Maps the JSON data type to a java.lang.String |
com.iciql.adapter.postgresql.JsonbStringAdapter | String | JSONB | Maps the JSONB data type to a java.lang.String |
com.iciql.adapter.postgresql.XmlStringAdapter | String | XML | Maps the XML data type to a java.lang.String |