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.
|