Skip to content
James Moger edited this page Apr 9, 2016 · 1 revision

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