aboutsummaryrefslogtreecommitdiffstats
path: root/src/site/dta.mkd
blob: 6795a0fa7b29fd29b4ce36fa01eef2092f849717 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
## 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> {

    @Override
    public String getDataType() {
        return "jsonb";
    }

    @Override
    public Class<Invoice> getJavaType() {
        return Invoice.class;
    }

    Gson gson() {
        return new GsonBuilder().create();
    }

    @Override
    public Object serialize(DcKey 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.

### 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 DataTypeAdapters

Not every DataTypeAdapter has to be a custom implementation.
The following adapters are included in Iciql for general purpose use.

- `com.iciql.adapter.JavaSerializationTypeAdapter`
Uses Java serialization to store/retrieve your objects as BLOBs.
- `com.iciql.adapter.GsonTypeAdapter`
Uses Google Gson to store/retrieve your objects as TEXT.
- `com.iciql.adapter.XmlTypeAdapter`
Uses XStream to store/retrieve your objects as TEXT.
- `com.iciql.adapter.postgres.GsonTypeAdapter`
Uses Google Gson to store/retrieve your objects as JSON for Postgres.
- `com.iciql.adapter.postgres.GsonBTypeAdapter`
Uses Google Gson to store/retrieve your objects as JSONB for Postgres.
- `com.iciql.adapter.postgres.XStreamTypeAdapter`
Uses XStream to store/retrieve your objects as XML for Postgres.
- `com.iciql.adapter.postgres.JsonStringAdapter`
Allows you to use the Postgres JSON data type with a standard String.
- `com.iciql.adapter.postgres.JsonbStringAdapter`
Allows you to use the Postgres JSONB data type with a standard String.
- `com.iciql.adapter.postgres.XmlStringAdapter`
Allows you to use the Postgres XML data type with a standard String.