arangodb-java-driver | ArangoDB | network protocol | Java version |
---|---|---|---|
4.2.x | 3.0.x, 3.1.x, 3.2.x | VelocyStream | 1.8+ |
4.1.x | 3.1.x | VelocyStream | 1.8+ |
To add the driver to your project with maven, add the following code to your pom.xml (please use a driver with a version number compatible to your ArangoDB server's version):
ArangoDB 3.2.X
<dependencies>
<dependency>
<groupId>com.arangodb</groupId>
<artifactId>arangodb-java-driver-async</artifactId>
<version>4.2.0</version>
</dependency>
</dependencies>
If you want to test with a snapshot version (e.g. 4.2.0-SNAPSHOT), add the staging repository of oss.sonatype.org to your pom.xml:
<repositories>
<repository>
<id>arangodb-snapshots</id>
<url>https://oss.sonatype.org/content/groups/staging</url>
</repository>
</repositories>
mvn clean install -DskipTests=true -Dgpg.skip=true -Dmaven.javadoc.skip=true -B
- Driver setup
- Manipulating databases
- Manipulating collections
- Basic Document operations
- Multi document operations
- AQL
- Graphs
- Foxx
- User management
- Serialization
- Learn more
Setup with default configuration, this automatically loads a properties file arangodb.properties if exists in the classpath:
// this instance is thread-safe
ArangoDB arangoDB = new ArangoDB.Builder().build();
The driver is configured with some default values:
property-key | description | default value |
---|---|---|
arangodb.hosts | ArangoDB hosts | 127.0.0.1:8529 |
arangodb.timeout | socket connect timeout(millisecond) | 0 |
arangodb.user | Basic Authentication User | |
arangodb.password | Basic Authentication Password | |
arangodb.useSsl | use SSL connection | false |
arangodb.chunksize | VelocyStream Chunk content-size(bytes) | 30000 |
arangodb.connections.max | max number of connections | 1 |
To customize the configuration the parameters can be changed in the code...
ArangoDB arangoDB = new ArangoDB.Builder().host("192.168.182.50", 8888).build();
... or with a custom properties file (my.properties)
InputStream in = MyClass.class.getResourceAsStream("my.properties");
ArangoDB arangoDB = new ArangoDB.Builder().loadProperties(in).build();
Example for arangodb.properties:
arangodb.hosts=127.0.0.1:8529,127.0.0.1:8529
arangodb.user=root
arangodb.password=
The drivers default used network protocol is the binary protocol VelocyStream which offers the best performance within the driver. To use HTTP, you have to set the configuration useProtocol
to Protocol.HTTP_JSON
for HTTP with Json content or Protocol.HTTP_VPACK
for HTTP with VelocyPack content.
ArangoDB arangoDB = new ArangoDB.Builder().useProtocol(Protocol.VST).build();
Note: If you are using ArangoDB 3.0.x you have to set the protocol to Protocol.HTTP_JSON
because it is the only one supported.
To use SSL, you have to set the configuration useSsl
to true
and set a SSLContext
. (see example code)
ArangoDB arangoDB = new ArangoDB.Builder().useSsl(true).sslContext(sc).build();
The driver supports connection pooling with a default of 1 maximum connections. To change this value use the method maxConnections(Integer)
in ArangoDB.Builder
.
ArangoDB arangoDB = new ArangoDB.Builder().maxConnections(8).build();
Since version 4.1.11
you can extend the VelocyPack serialization by registering additional VPackModule
s on ArangoDB.Builder
.
Added support for:
- java.time.Instant
- java.time.LocalDate
- java.time.LocalDateTime
- java.util.Optional;
- java.util.OptionalDouble;
- java.util.OptionalInt;
- java.util.OptionalLong;
<dependencies>
<dependency>
<groupId>com.arangodb</groupId>
<artifactId>velocypack-module-jdk8</artifactId>
<version>1.0.1</version>
</dependency>
</dependencies>
ArangoDB arangoDB = new ArangoDB.Builder().registerModule(new VPackJdk8Module()).build();
Added support for:
- scala.Option
- scala.collection.immutable.List
- scala.collection.immutable.Map
<dependencies>
<dependency>
<groupId>com.arangodb</groupId>
<artifactId>velocypack-module-scala</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
val arangoDB: ArangoDB = new ArangoDB.Builder().registerModule(new VPackScalaModule).build
Added support for:
- org.joda.time.DateTime;
- org.joda.time.Instant;
- org.joda.time.LocalDate;
- org.joda.time.LocalDateTime;
<dependencies>
<dependency>
<groupId>com.arangodb</groupId>
<artifactId>velocypack-module-joda</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
ArangoDBAsync arangoDB = new ArangoDBAsync.Builder().registerModule(new VPackJodaModule()).build();
ArangoDBAsync arangoDB = new ArangoDBAsync.Builder().registerModule(new VPackModule() {
@Override
public <C extends VPackSetupContext<C>> void setup(final C context) {
context.registerDeserializer(MyObject.class, new VPackDeserializer<MyObject>() {
@Override
public MyObject deserialize(VPackSlice parent,VPackSlice vpack,
VPackDeserializationContext context) throws VPackException {
MyObject obj = new MyObject();
obj.setName(vpack.get("name").getAsString());
return obj;
}
});
context.registerSerializer(MyObject.class, new VPackSerializer<MyObject>() {
@Override
public void serialize(VPackBuilder builder,String attribute,MyObject value,
VPackSerializationContext context) throws VPackException {
builder.add(attribute, ValueType.OBJECT);
builder.add("name", value.getName());
builder.close();
}
});
}
}).build();
// create database
arangoDB.createDatabase("myDatabase");
// drop database
arangoDB.db("myDatabase").drop();
// create collection
arangoDB.db("myDatabase").createCollection("myCollection", null);
// delete collection
arangoDB.db("myDatabase").collection("myCollection").drop();
arangoDB.db("myDatabase").collection("myCollection").truncate();
Every document operations works with POJOs (e.g. MyObject), VelocyPack (VPackSlice) and Json (String).
For the next examples we use a small object:
public class MyObject {
private String key;
private String name;
private int age;
public MyObject(String name, int age) {
this();
this.name = name;
this.age = age;
}
public MyObject() {
super();
}
/*
* + getter and setter
*/
}
MyObject myObject = new MyObject("Homer", 38);
arangoDB.db("myDatabase").collection("myCollection").insertDocument(myObject);
When creating a document, the attributes of the object will be stored as key-value pair E.g. in the previous example the object was stored as follows:
"name" : "Homer"
"age" : "38"
arangoDB.db("myDatabase").collection("myCollection").deleteDocument(myObject.getKey());
arangoDB.db("myDatabase").collection("myCollection").updateDocument(myObject.getKey(), myUpdatedObject);
arangoDB.db("myDatabase").collection("myCollection").replaceDocument(myObject.getKey(), myObject2);
arangoDB.db("myDatabase").collection("myCollection").getDocument(myObject.getKey(), MyObject.class).thenAccept(document -> {
document.getName();
document.getAge();
}
VPackSlice document = arangoDB.db("myDatabase").collection("myCollection").getDocument(myObject.getKey(), VPackSlice.class).thenAccept(document -> {
document.get("name").getAsString();
document.get("age").getAsInt();
}
arangoDB.db("myDatabase").collection("myCollection").getDocument(myObject.getKey(), String.class).thenAccept(document -> {
}
arangoDB.db("myDatabase").collection("myCollection").getDocument("myKey", MyObject.class);
arangoDB.db("myDatabase").getDocument("myCollection/myKey", MyObject.class);
Collection<MyObject> documents = new ArrayList<>;
documents.add(myObject1);
documents.add(myObject2);
documents.add(myObject3);
arangoDB.db("myDatabase").collection("myCollection").insertDocuments(documents);
Collection<String> keys = new ArrayList<>;
keys.add(myObject1.getKey());
keys.add(myObject2.getKey());
keys.add(myObject3.getKey());
arangoDB.db("myDatabase").collection("myCollection").deleteDocuments(keys);
Collection<MyObject> documents = new ArrayList<>;
documents.add(myObject1);
documents.add(myObject2);
documents.add(myObject3);
arangoDB.db("myDatabase").collection("myCollection").updateDocuments(documents);
Collection<MyObject> documents = new ArrayList<>;
documents.add(myObject1);
documents.add(myObject2);
documents.add(myObject3);
arangoDB.db("myDatabase").collection("myCollection").replaceDocuments(documents);
Every AQL operations works with POJOs (e.g. MyObject), VelocyPack (VPackSlice) and Json (String).
E.g. get all Simpsons aged 3 or older in ascending order:
arangoDB.createDatabase("myDatabase");
ArangoDatabaseAsync db = arangoDB.db("myDatabase");
db.createCollection("myCollection");
ArangoCollectionAsync collection = db.collection("myCollection");
collection.insertDocument(new MyObject("Homer", 38)).get();
collection.insertDocument(new MyObject("Marge", 36)).get();
collection.insertDocument(new MyObject("Bart", 10)).get();
collection.insertDocument(new MyObject("Lisa", 8)).get();
collection.insertDocument(new MyObject("Maggie", 2)).get();
Map<String, Object> bindVars = new HashMap<>();
bindVars.put("age", 3);
db.query(query, bindVars, null, MyObject.class).thenAccept(cursor -> {
cursor.forEachRemaining(obj -> {
System.out.println(obj.getName());
});
});
or return the AQL result as VelocyPack:
db.query(query, bindVars, null, VPackSlice.class).thenAccept(cursor -> {
cursor.forEachRemaining(obj -> {
System.out.println(obj.get("name").getAsString());
});
});
Note: The parameter type
in query()
has to match the result of the query, otherwise you get an VPackParserException. E.g. you set type
to BaseDocument
or a POJO and the query result is an array or simple type, you get an VPackParserException caused by VPackValueTypeException: Expecting type OBJECT.
The driver supports the graph api.
Some of the basic graph operations are described in the following:
##add graph A graph consists of vertices and edges (stored in collections). Which collections are used within a graph is defined via edge definitions. A graph can contain more than one edge definition, at least one is needed.
Collection<EdgeDefinition> edgeDefinitions = new ArrayList<>();
EdgeDefinition edgeDefinition = new EdgeDefinition();
// define the edgeCollection to store the edges
edgeDefinition.collection("myEdgeCollection");
// define a set of collections where an edge is going out...
edgeDefinition.from("myCollection1", "myCollection2");
// repeat this for the collections where an edge is going into
edgeDefinition.to("myCollection1", "myCollection3");
edgeDefinitions.add(edgeDefinition);
// A graph can contain additional vertex collections, defined in the set of orphan collections
GraphCreateOptions options = new GraphCreateOptions();
options.orphanCollections("myCollection4", "myCollection5");
// now it's possible to create a graph
arangoDB.db("myDatabase").createGraph("myGraph", edgeDefinitions, options);
A graph can be deleted by its name
arangoDB.db("myDatabase").graph("myGraph").drop();
Vertices are stored in the vertex collections defined above.
MyObject myObject1 = new MyObject("Homer", 38);
MyObject myObject2 = new MyObject("Marge", 36);
arangoDB.db("myDatabase").graph("myGraph").vertexCollection("collection1").insertVertex(myObject1, null);
arangoDB.db("myDatabase").graph("myGraph").vertexCollection("collection3").insertVertex(myObject2, null);
Now an edge can be created to set a relation between vertices
arangoDB.db("myDatabase").graph("myGraph").edgeCollection("myEdgeCollection").insertEdge(myEdgeObject, null);
Request request = new Request("mydb", RequestType.GET, "/my/foxx/service")
CompletableFuture<Response> response = arangoDB.executeAsync(request);
If you are using [authentication] (https://docs.arangodb.com/Manual/GettingStarted/Authentication.html) you can manage users with the driver.
//username, password
arangoDB.createUser("myUser", "myPassword");
arangoDB.deleteUser("myUser");
arangoDB.getUsers().thenAccept(users -> {
for(UserResult user : users) {
System.out.println(user.getUser())
}
});
arangoDB.db("myDatabase").grantAccess("myUser");
arangoDB.db("myDatabase").revokeAccess("myUser");
The driver can serialize/deserialize JavaBeans. They need at least a constructor without parameter.
public class MyObject {
private String name;
private Gender gender;
private int age;
public MyObject() {
super();
}
}
To use Arango-internal fields (like _id, _key, _rev, _from, _to) in your JavaBeans, use the annotation DocumentField
.
public class MyObject {
@DocumentField(Type.KEY)
private String key;
private String name;
private Gender gender;
private int age;
public MyObject() {
super();
}
}
To use a different serialized name for a field, use the annotation SerializedName
.
public class MyObject {
@SerializedName("title")
private String name;
private Gender gender;
private int age;
public MyObject() {
super();
}
}
To ignore fields at serialization/deserialization, use the annotation Expose
public class MyObject {
@Expose
private String name;
@Expose(serialize = true, deserialize = false)
private Gender gender;
private int age;
public MyObject() {
super();
}
}
ArangoDBAsync arangoDB = new ArangoDBAsync.Builder().registerModule(new VPackModule() {
@Override
public <C extends VPackSetupContext<C>> void setup(final C context) {
context.registerDeserializer(MyObject.class, new VPackDeserializer<MyObject>() {
@Override
public MyObject deserialize(VPackSlice parent,VPackSlice vpack,
VPackDeserializationContext context) throws VPackException {
MyObject obj = new MyObject();
obj.setName(vpack.get("name").getAsString());
return obj;
}
});
context.registerSerializer(MyObject.class, new VPackSerializer<MyObject>() {
@Override
public void serialize(VPackBuilder builder,String attribute,MyObject value,
VPackSerializationContext context) throws VPackException {
builder.add(attribute, ValueType.OBJECT);
builder.add("name", value.getName());
builder.close();
}
});
}
}).build();
To de-/serialize from and to VelocyPack before or after a database call, use the ArangoUtil
from the method util()
in ArangoDB
, ArangoDatabase
, ArangoCollection
, ArangoGraph
, ArangoEdgeCollection
or ArangoVertexCollection
.
ArangoDBAsync arangoDB = new ArangoDBAsync.Builder();
VPackSlice vpack = arangoDB.util().serialize(myObj);
ArangoDBAsync arangoDB = new ArangoDBAsync.Builder();
MyObject myObj = arangoDB.util().deserialize(vpack, MyObject.class);