## 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](http://www.postgresql.org/docs/9.4/static/datatype-json.html) in 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. ---JAVA--- @IQTable public class Invoices { @IQColumn(primaryKey = true, autoIncrement = true) public long _id; @IQColumn Date received; @IQColumn @TypeAdapter(InvoiceAdapterImpl.class) Invoice invoice; } ---JAVA--- 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*. ---JAVA--- 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; } } ---JAVA--- Here you can see how the *InvoiceTypeAdapter* defines a [Postgres JSONB data type](http://www.postgresql.org/docs/9.4/static/datatype-json.html) and automatically handles JSON (de)serialization with [Google Gson](https://code.google.com/p/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. ---JAVA--- @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER }) @TypeAdapter(InvoiceAdapterImpl.class) public @interface InvoiceAdapter { } ---JAVA--- ### Included Data Type Adapters The following adapters are included in Iciql. They may require an optional dependency such as Gson, XStream, or SnakeYaml. <table class="table"> <tr><td colspan="4"><b>Common Type Adapters</b></tr> <tr><td><i>Adapter</i></td><td><i>Java</i></td><td><i>SQL</i></td><td><i>Description</i></td></tr> <tr><td>com.iciql.adapter.JavaSerializationTypeAdapter</td><td>Object</td><td>BLOB</td><td>Uses Java serialization to (de)serialize your object</td></tr> <tr><td>com.iciql.adapter.GsonTypeAdapter<T></td><td><T></td><td>TEXT</td><td> Uses Google Gson to (de)serialize your object as JSON</td></tr> <tr><td>com.iciql.adapter.XStreamTypeAdapter</td><td>Object</td><td>TEXT</td><td> Uses XStream to (de)serialize your object as XML</td></tr> <tr><td>com.iciql.adapter.SnakeYamlTypeAdapter<T></td><td><T></td><td>TEXT</td><td> Uses SnakeYaml to (de)serialize your object as YAML</td></tr> <tr><td colspan="4"><b>PostgreSQL Type Adapters</b></tr> <tr><td><i>Object Adapters</i></td><td><i>Java</i></td><td><i>SQL</i></td><td><i>Description</i></td></tr> <tr><td>com.iciql.adapter.postgresql.JsonObjectAdapter<T></td><td><T></td><td>JSON</td><td> Uses Google Gson to (de)serialize your object as JSON</td></tr> <tr><td>com.iciql.adapter.postgresql.JsonbObjectAdapter<T></td><td><T></td><td>JSONB</td><td> Uses Google Gson to (de)serialize your object as JSONB</td></tr> <tr><td>com.iciql.adapter.postgresql.XmlObjectAdapter</td><td>Object</td><td>XML</td><td> Uses XStream to (de)serialize your object as XML</td></tr> <tr><td colspan="4"><i>String Adapters</i></td></tr> <tr><td>com.iciql.adapter.postgresql.JsonStringAdapter</td><td>String</td><td>JSON</td><td> Maps the JSON data type to a java.lang.String</td></tr> <tr><td>com.iciql.adapter.postgresql.JsonbStringAdapter</td><td>String</td><td>JSONB</td><td> Maps the JSONB data type to a java.lang.String</td></tr> <tr><td>com.iciql.adapter.postgresql.XmlStringAdapter</td><td>String</td><td>XML</td><td> Maps the XML data type to a java.lang.String</td></tr> </table>