-
Notifications
You must be signed in to change notification settings - Fork 23
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 |