|
1 | 1 | ## User-defined types |
2 | 2 |
|
3 | | -*Coming soon... In the meantime, see the javadoc for [UserType].* |
| 3 | +[CQL user-defined types][cql_doc] are ordered sets of named, typed fields. They must be defined in a |
| 4 | +keyspace: |
4 | 5 |
|
5 | | -[UserType]: http://docs.datastax.com/en/drivers/java/3.6/com/datastax/driver/core/UserType.html |
| 6 | +``` |
| 7 | +CREATE TYPE ks.type1 ( |
| 8 | + a int, |
| 9 | + b text, |
| 10 | + c float); |
| 11 | +``` |
| 12 | + |
| 13 | +And can then be used as a column type in tables, or a field type in other user-defined types in that |
| 14 | +keyspace: |
| 15 | + |
| 16 | +``` |
| 17 | +CREATE TABLE ks.collect_things ( |
| 18 | + pk int, |
| 19 | + ck1 text, |
| 20 | + ck2 text, |
| 21 | + v frozen<type1>, |
| 22 | + PRIMARY KEY (pk, ck1, ck2) |
| 23 | +); |
| 24 | +
|
| 25 | +CREATE TYPE ks.type2 (v frozen<type1>); |
| 26 | +``` |
| 27 | + |
| 28 | +### Fetching UDTs from results |
| 29 | + |
| 30 | +The driver maps UDT columns to the [UDTValue] class, which exposes getters and setters to access |
| 31 | +individual fields by index or name: |
| 32 | + |
| 33 | +```java |
| 34 | +Row row = session.execute("SELECT v FROM ks.collect_things WHERE pk = 1").one(); |
| 35 | + |
| 36 | +UDTValue udtValue = row.getUDTValue("v"); |
| 37 | +int a = udtValue.getInt(0); |
| 38 | +String b = udtValue.getString("b"); |
| 39 | +Float c = udtValue.getFloat(2); |
| 40 | +``` |
| 41 | + |
| 42 | +### Using UDTs as parameters |
| 43 | + |
| 44 | +Statements may contain UDTs as bound values: |
| 45 | + |
| 46 | +```java |
| 47 | +PreparedStatement ps = |
| 48 | + session.prepare( |
| 49 | + "INSERT INTO ks.collect_things (pk, ck1, ck2, v) VALUES (:pk, :ck1, :ck2, :v)"); |
| 50 | +``` |
| 51 | + |
| 52 | +To create a new UDT value, you must first have a reference to its [UserType]. There are |
| 53 | +various ways to get it: |
| 54 | + |
| 55 | +* from the statement's metadata |
| 56 | + |
| 57 | + ```java |
| 58 | + UserType udt = (UserType) ps.getVariables().getType("v"); |
| 59 | + ``` |
| 60 | + |
| 61 | +* from the driver's [schema metadata](../metadata/#schema-metadata): |
| 62 | +
|
| 63 | + ```java |
| 64 | + UserType udt = session.getMetadata().getKeyspace("ks").getUserType("type1"); |
| 65 | + ``` |
| 66 | +
|
| 67 | +* from another UDT value: |
| 68 | +
|
| 69 | + ```java |
| 70 | + UserType udt = udtValue.getType(); |
| 71 | + ``` |
| 72 | + |
| 73 | +Note that the driver's official API does not expose a way to build [UserType] instances manually. |
| 74 | +This is because the type's internal definition must precisely match the database schema; |
| 75 | +if it doesn't (for example if the fields are not in the same order), you run the risk of inserting |
| 76 | +corrupt data, that you won't be able to read back. |
| 77 | + |
| 78 | +Once you have the type, call `newValue()` and set the fields: |
| 79 | +
|
| 80 | +```java |
| 81 | +UDTValue udtValue = udt.newValue().setInt(0, 1).setString(1, "hello").setFloat(2, 2.3f); |
| 82 | +``` |
| 83 | +
|
| 84 | +And bind your UDT value like any other type: |
| 85 | +
|
| 86 | +```java |
| 87 | +BoundStatement bs = |
| 88 | + ps.bind() |
| 89 | + .setInt("pk", 1) |
| 90 | + .setString("ck1", "1") |
| 91 | + .setString("ck2", "1") |
| 92 | + .setUDTValue("v", udtValue); |
| 93 | +session.execute(bs); |
| 94 | +``` |
| 95 | +
|
| 96 | +[cql_doc]: https://docs.datastax.com/en/cql/3.3/cql/cql_reference/cqlRefUDType.html |
| 97 | +
|
| 98 | +[UDTValue]: https://docs.datastax.com/en/drivers/java/3.6/com/datastax/driver/core/UDTValue.html |
| 99 | +[UserType]: https://docs.datastax.com/en/drivers/java/3.6/com/datastax/driver/core/UserType.html |
0 commit comments