-
Notifications
You must be signed in to change notification settings - Fork 26
Data Type Adapters
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.
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.
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.
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 { }
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 |