Skip to content

Commit bbc658c

Browse files
authored
Readme table of contents (#13)
* Add table of contents to README.md.
1 parent 10b88ba commit bbc658c

File tree

1 file changed

+55
-33
lines changed

1 file changed

+55
-33
lines changed

README.md

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,36 @@
11
# Aerospike Java Object Mapper
22

3-
[Aerospike](https://www.aerospike.com) is one of, if not the fastest, NoSQL database in the world. It presents a Java API which is comprehensive and powerful, but requires a measure of boilder plate code to map the data from Java POJOs to the database. The aim of this repository is to lower the amount of code required when mapping POJOs to Aerospike and back as well as reducing some of the brittleness of the code.
4-
3+
[Aerospike](https://www.aerospike.com) is one of, if not the fastest, NoSQL database in the world. It presents a Java API which is comprehensive and powerful, but requires a measure of boiler plate code to map the data from Java POJOs to the database. The aim of this repository is to lower the amount of code required when mapping POJOs to Aerospike and back as well as reducing some of the brittleness of the code.
4+
5+
# Table of contents:
6+
1. [Motivation and a simple example](#Motivation-and-a-simple-example)
7+
2. [Getting Started](#Getting-Started)
8+
3. [Constructors](#Constructors)
9+
4. [Keys](#Keys)
10+
5. [Fields](#Fields)
11+
6. [Properties](#Properties)
12+
7. [References to other objects](#References-to-other-objects)
13+
+ 7.1. [Associating by Reference](#Associating-by-Reference)
14+
+ 7.2. [Aggregating by Embedding](#Aggregating-by-Embedding)
15+
+ 7.2.1. [Versioning Lists](#Versioning-Lists)
16+
+ 7.2.2 [List Ordinals](#List-Ordinals)
17+
+ 7.2.3 [The importance of Generic Types](#The-importance-of-Generic-Types)
18+
8. [Advanced Features](#Advanced-Features)
19+
+ 8.1. [Placeholder replacement](#Placeholder-replacement)
20+
+ 8.2. [Subclasses](#Subclasses)
21+
+ 8.2.1 [Data Inheritance](#Data-Inheritance)
22+
+ 8.2.2 [Subclass Inheritance](#Subclass-Inheritance)
23+
+ 8.3. [Custom Object Converters](#Custom-Object-Converters)
24+
9. [External Configuration File](#External-Configuration-File)
25+
+ 9.1 [File Structure](#File-Structure)
26+
+ 9.1.1 [Key Structure](#Key-Structure)
27+
+ 9.1.2 [Bin Structure](#Bin-Structure)
28+
+ 9.1.3 [Embed Structure](#Embed-Structure)
29+
+ 9.1.4 [Reference Structure](#Reference-Structure)
30+
10. [Virtual Lists](#Virtual-Lists)
31+
11. [To finish](#To-finish)
32+
33+
# Motivation and a simple example
534
Consider a simple class:
635

736
```java
@@ -248,14 +277,14 @@ However, there are times when this is not desirable, for example when the class
248277
249278
```java
250279
@AerospikeRecord(namespace = "test", set = "testSet")
251-
public class ConstructoredClass {
280+
public class ConstructedClass {
252281
@AerospikeKey
253282
public final int id;
254283
public final int age;
255284
public final String name;
256285
public final Date date;
257286
258-
public ConstructoredClass(int id, int age, String name, Date date) {
287+
public ConstructedClass(int id, int age, String name, Date date) {
259288
super();
260289
this.id = id;
261290
this.age = age;
@@ -265,18 +294,18 @@ public class ConstructoredClass {
265294
}
266295
```
267296
268-
As it stands, this class cannot be used with the AeroMapper because there is no valid constructor to invoke when an object needs to be created. There is a constructor but it does not contain enough information to map the reocrd on the database to the parameters of the constructor. (Remember that at runtime method and argument names are typically lost and become "arg1", "arg2" and so on). We can use this constructor, but we need to provide this missing information with annotations:
297+
As it stands, this class cannot be used with the AeroMapper because there is no valid constructor to invoke when an object needs to be created. There is a constructor but it does not contain enough information to map the record on the database to the parameters of the constructor. (Remember that at runtime method and argument names are typically lost and become "arg1", "arg2" and so on). We can use this constructor, but we need to provide this missing information with annotations:
269298
270299
```java
271300
@AerospikeRecord(namespace = "test", set = "testSet")
272-
public class ConstructoredClass {
301+
public class ConstructedClass {
273302
@AerospikeKey
274303
public final int id;
275304
public final int age;
276305
public final String name;
277306
public final Date date;
278307
279-
public ConstructoredClass(@ParamFrom("id") int id, @ParamFrom("age") int age, @ParamFrom("name") String name, @ParamFrom("date")Date date) {
308+
public ConstructedClass(@ParamFrom("id") int id, @ParamFrom("age") int age, @ParamFrom("name") String name, @ParamFrom("date")Date date) {
280309
super();
281310
this.id = id;
282311
this.age = age;
@@ -305,14 +334,14 @@ Note that not all the fields in the class need to be specified in the constructo
305334
306335
```java
307336
@AerospikeRecord(namespace = "test", set = "testSet")
308-
public class ConstructoredClass2 {
337+
public class ConstructedClass2 {
309338
@AerospikeKey
310339
public final int id;
311340
public final int a;
312341
public int b;
313342
public int c;
314343
315-
public ConstructoredClass2(@ParamFrom("id") int id, @ParamFrom("a") int a) {
344+
public ConstructedClass2(@ParamFrom("id") int id, @ParamFrom("a") int a) {
316345
this.id = id;
317346
this.a = a;
318347
}
@@ -325,19 +354,19 @@ If there are multiple constructors on the class, the one to be used by the AeroM
325354
326355
```java
327356
@AerospikeRecord(namespace = "test", set = "testSet")
328-
public class ConstructoredClass2 {
357+
public class ConstructedClass2 {
329358
@AerospikeKey
330359
public final int id;
331360
public final int a;
332361
public int b;
333362
public int c;
334363
335-
public ConstructoredClass2(@ParamFrom("id") int id, @ParamFrom("a") int a) {
364+
public ConstructedClass2(@ParamFrom("id") int id, @ParamFrom("a") int a) {
336365
this.id = id;
337366
this.a = a;
338367
}
339368
@AerospikeConstructor
340-
public ConstructoredClass2(@ParamFrom("id") int id, @ParamFrom("a") int a, @ParamFrom("b") int b) {
369+
public ConstructedClass2(@ParamFrom("id") int id, @ParamFrom("a") int a, @ParamFrom("b") int b) {
341370
this.id = id;
342371
this.a = a;
343372
this.b = b;
@@ -810,7 +839,7 @@ loadedPerson : Person
810839
811840
Note that if a reference to an AerospikeRecord annotated object exists, but the reference has neither @AerospikeReference nor @AerospikeEmbed (see below), then it is assumed it will be @AerospikeReference(lazy = false).
812841
813-
There are times when it makes sense to store the digest of the child record as the reference rather than it's primary key. For example, if the native primary key is of significant length then storing a fixed 20-byte digest makes sense. This can be accomplished by adding `type = ReferenceType.DIGEST` to the @AeropikeReference. For example:
842+
There are times when it makes sense to store the digest of the child record as the reference rather than it's primary key. For example, if the native primary key is of significant length then storing a fixed 20-byte digest makes sense. This can be accomplished by adding `type = ReferenceType.DIGEST` to the @AerospikeReference. For example:
814843

815844
```java
816845
@AerospikeRecord(namespace = "test", set = "people")
@@ -1162,7 +1191,7 @@ transactions: MAP('{"Txn1":[100, 1610478132904000000, "Bob's store", "Txn1"], "T
11621191
type: "SAVINGS"
11631192
```
11641193
1165-
Here the transaction time is the second attribute in each list, and the amount is the first attribute. However, a common request is to be able to extract transaction by time. For example, in fraud detection systems, there may be a need to load the N most recent transactions. If the transactions were to be stored with the transaction time as the first element in the list, efficient CDT perations in Aerospike such as `getByValueRange(...)` can be used.
1194+
Here the transaction time is the second attribute in each list, and the amount is the first attribute. However, a common request is to be able to extract transaction by time. For example, in fraud detection systems, there may be a need to load the N most recent transactions. If the transactions were to be stored with the transaction time as the first element in the list, efficient CDT operations in Aerospike such as `getByValueRange(...)` can be used.
11661195
11671196
This ordering can be controlled by the @AerospikeOrdinal annotation:
11681197
@@ -1302,7 +1331,7 @@ An example using an environment variable:
13021331
private String title;
13031332
```
13041333

1305-
In this case, if the environment variable ``ACCOUNT_TITLE_BIN_NAME`` is set, that will be the name of the bin which is used. If it is not set, it will be like the annotation does not specify the ``name`` paramteter at all, which means that the field name (``title``) will be used for the bin name.
1334+
In this case, if the environment variable ``ACCOUNT_TITLE_BIN_NAME`` is set, that will be the name of the bin which is used. If it is not set, it will be like the annotation does not specify the ``name`` parameter at all, which means that the field name (``title``) will be used for the bin name.
13061335

13071336
----
13081337

@@ -1597,7 +1626,7 @@ Sometimes, the representation of the data in Aerospike and the representation in
15971626

15981627
```java
15991628
public enum Suit {
1600-
CLUBS, DIAMONDS, HEARTS, SPADES;
1629+
CLUBS, DIAMONDS, HEARTS, SPADES
16011630
}
16021631

16031632
@AerospikeRecord(namespace = NAMESPACE, set = "card")
@@ -1841,14 +1870,15 @@ Top level is an array of classes. Each class has:
18411870
- **key**: a [key structure](key-structure), specified below
18421871
- **bins**: a list of [bin structure](bin-structure), specified below
18431872
- **version**: The version of the record. Must be an integer with a positive value. If not specified, will default to 1. See [Versioning Links](#versioning-lists) for more details.
1844-
1873+
18451874
#### Key Structure
1846-
The key structure contains:
1847-
- **field**: the field for the key. Can be unspecified if methods are being used for the key
1848-
- **getter**: the name of the method to be used as the getter for the key.
1849-
- **setter**: the name of the method to be used as the setter for the key. This is optional -- if lazy loading of referenced objects is used, a setter must be specified for the child class if a getter is
1850-
Note that either a field should be specified, or a getter (potentially with a setter). Using both a field and a getter will throw an error. Also note that the method is specified by names only, not parameters so it is a good idea to us a unique method.
1851-
1875+
The key structure is used to specify the key to a record. Keys are optional in some situations. For example, if Object A embeds an Object B, B does not need a key as it is not stored in Aerospike in its own right.
1876+
1877+
The key structure contains:
1878+
- **field**: The name of the field which to which this key is mapped. If this is provided, the getter and setter cannot be provided.
1879+
- **getter**: The getter method used to populate the key. This must be used in conjunction with a setter method, and excludes the use of the field attribute.
1880+
- **setter**: The setter method used to map data back to the Java key. This is used in conjunction with the getter method and precludes the use of the field attribute. Note that the return type of the getter must match the type of the first parameter of the setter, and the setter can have either 1 or 2 parameters, with the second (optional) parameter being either of type [com.aerospike.client.Key](https://www.aerospike.com/apidocs/java/com/aerospike/client/Key.html) or Object.
1881+
18521882
#### Bin Structure
18531883
The bin structure contains:
18541884
- **embed**: An [embed structure](#embed-structure) used for specifying that the contents of this bin should be included in the parent record, rather than being a reference to a child record. There can only be one embed structure per field, and if an embed structure is present, a [reference structure](#reference-structure) cannot be. If a field refers to another AerospikeRecord, either in a collection or in it's own right, and neither an embed or reference structure is specified, a reference will be assumed by default.
@@ -1859,14 +1889,6 @@ The bin structure contains:
18591889
- **ordinal**: For items mapped as lists, this ordinal specifies the location of this bin in the list. If this is not provided, the position of the bins in the list will be determined by alphabetical ordering.
18601890
- **reference**: A [reference structure](#reference-structure) detailing that a child object referenced by this bin should be stored as the key of the child rather than embedding it in the parent object. The use of a reference precludes the use of the embed attribute, and if neither is specified then reference is assumed as the default.
18611891
- **setter**: The setter method used to map data back to the Java POJO. This is used in conjunction with the getter method and precludes the use of the field attribute. Note that the return type of the getter must match the type of the first parameter of the setter, and the setter can have either 1 or 2 parameters, with the second (optional) parameter being either of type [com.aerospike.client.Key](https://www.aerospike.com/apidocs/java/com/aerospike/client/Key.html) or Object.
1862-
1863-
#### Key Structure
1864-
The key structure is used to specify the key to a record. Keys are optional in some situations. For example, if Object A embeds an Object B, B does not need a key as it is not stored in Aerospike in its own right.
1865-
1866-
The key structure contains:
1867-
- **field**: The name of the field which to which this key is mapped. If this is provided, the getter and setter cannot be provided.
1868-
- **getter**: The getter method used to populate the key. This must be used in conjunction with a setter method, and excludes the use of the field attribute.
1869-
- **setter**: The setter method used to map data back to the Java key. This is used in conjunction with the getter method and precludes the use of the field attribute. Note that the return type of the getter must match the type of the first parameter of the setter, and the setter can have either 1 or 2 parameters, with the second (optional) parameter being either of type [com.aerospike.client.Key](https://www.aerospike.com/apidocs/java/com/aerospike/client/Key.html) or Object.
18701892

18711893
#### Embed Structure
18721894
The embed structure is used when a child object should be fully contained in the parent object without needing to be stored in the database as a separate record. For example, it might be that Customer object contains an Address, but the Address is not stored in a separate table in Aerospike, but rather put into the database as part of the customer record.
@@ -1941,7 +1963,7 @@ public class Container {
19411963
}
19421964
````
19431965

1944-
Note that in this case the items are embedded into the container and not refrenced. This is what is needed for virtual lists, they must have a list of items in the database associated with a single record.
1966+
Note that in this case the items are embedded into the container and not referenced. This is what is needed for virtual lists, they must have a list of items in the database associated with a single record.
19451967

19461968
These items can be populated using the functionally presented above. For example:
19471969

@@ -2001,7 +2023,7 @@ name: "container"
20012023
```
20022024
20032025
Note however that the list in the object in memory still contains only 4 items. *Virtual lists affect only the database representation of the data and not the Java POJO.*
2004-
eVirutal Lists tend to use the (Operate)[https://www.aerospike.com/docs/client/java/usage/kvs/multiops.html] command which allows multiple operations to be performed on the same key at the same time. As a consequence, multiple commands can be done on a list with a single Aerospike operation. For example:
2026+
Virtual Lists tend to use the (Operate)[https://www.aerospike.com/docs/client/java/usage/kvs/multiops.html] command which allows multiple operations to be performed on the same key at the same time. As a consequence, multiple commands can be done on a list with a single Aerospike operation. For example:
20052027
20062028
```java
20072029
List<Item> results = (List<Item>) list.beginMultiOperation()

0 commit comments

Comments
 (0)