Per aggiungere il driver ad un progetto Java, si può usare Gradle o Maven, ed è sufficiente includere la dipendenza a neo4j-java-driver (attualmente la versione raccomandata è la 1.3). Nel caso di Maven, aggiungiamo nel file pom.xml:
<dependencies>
<dependency>
<groupId>org.neo4j.driver</groupId>
<artifactId>neo4j-java-driver</artifactId>
<version>1.3.0</version>
</dependency>
</dependencies>
Una volta che Maven ha aggiornato le dipendenze, possiamo connetterci al database per eseguire delle query in Cypher. Vediamo un esempio breve ma completo, con alcune delle query viste nelle lezioni precedenti.
import org.neo4j.driver.v1;
Driver driver = GraphDatabase.driver("bolt://localhost");
try (Session session = driver.session()) {
Statement statement = new Statement(
"MATCH (u:User) WHERE u.name ENDS WITH {searchText} RETURN u.name");
StatementResult cursor = session.run(
statement.withParameters(
Values.parameters( "searchText", "@html.it" ) ));
while (result.hasNext()) {
Record record = result.next();
String name = record.get("name").asString();
// TODO: usare name
}
// Transazione
try (Transaction transaction = session.beginTransaction()) {
transaction.run(
"CREATE(u:User {name: {new_user}})",
Values.parameters("new_user", "newUser@html.it"));
transation.success();
}
}
A parte l'importazione delle classi e delle interfacce necessarie, nella prima riga vediamo come si inizializza il driver. L'oggetto Driver
è thread-safe. Esso è stato pensato per essere inizializzato una volta sola nel ciclo di vita dell'applicazione (nel caso di applicazione web potrebbe essere un singleton iniettato dal container), in modo che esista una sola istanza di Driver
per ogni database da utilizzare. Sua responsabilità è anche quella di mantenere un pool di connessioni per velocizzare la creazione di sessioni. Come si vede dal codice precedente, abbiamo utilizzato una URL di connessione al servizio che comincia con il protocollo proprietario, ovvero con bolt://
.
Nel primo blocco try
vediamo il tipico utilizzo di una sessione. Poiché ogni sessione rappresenta una connessione TCP al database, il blocco ci garantisce che all'uscita la sessione viene chiusa e la connessione rilasciata per poter essere riutilizzata.
Uno Statement
rappresenta una query Cypher da eseguire con un elenco di parametri (opzionali). Tali parametri possono essere passati anche con il metodo Session.run
, come vediamo nella riga successiva. Notare come i parametri siano indicati nella query con parentesi graffe. Utilizzare i parametri invece di valori letterali cablati nelle query può avere impatti molto positivi sulle performance delle query, soprattutto se le query effettuate vengono eseguite più volte, come avviene normalmente nella maggioranza delle applicazioni. I risultati, come si fa comunemente con le librerie di accesso ai dati, possono essere letti attraverso un cursore che deve essere iterato.
Nel secondo blocco try
vediamo la creazione di una transazione. Una transazione rende atomica la sequenza di operazioni che contiene: se facciamo un certo numero di modifiche sul database (creazioni, modifiche, cancellazioni) ed una qualsiasi di esse (in qualsiasi posizione della sequenza) fallisce per un errore, anche le altre vengono annullate riportando tutto alla situazione iniziale (rollback). In questo esempio c'è una sola operazione, di fatto rendendo inutile la creazione della transazione: infatti, Neo4j prevede il concetto di autocommit transaction, grazie al quale un'istruzione fuori di transazione causa implicitamente la creazione e il commit di una transazione.