Introduzione a Spring Data Neo4j

1. Panoramica

Questo articolo è un'introduzione a Spring Data Neo4j , il popolare database di grafici.

Spring Data Neo4j consente lo sviluppo basato su POJO per Neo4j Graph Database e utilizza concetti Spring familiari come classi modello per l'utilizzo di API di base e fornisce un modello di programmazione basato su annotazioni.

Inoltre, molti sviluppatori non sanno davvero se Neo4j sarà effettivamente una buona soluzione per le loro esigenze specifiche; ecco una solida panoramica su Stackoverflow che spiega perché utilizzare Neo4j e i pro e i contro.

2. Dipendenze di Maven

Cominciamo dichiarando le dipendenze Spring Data Neo4j nel pom.xml. I moduli Spring sotto menzionati sono necessari anche per Spring Data Neo4j:

 org.springframework.data spring-data-neo4j 5.0.1.RELEASE   org.neo4j neo4j-ogm-test 3.1.2 test 

Queste dipendenze includono anche i moduli richiesti per il test.

Nota che l'ultima dipendenza ha l'ambito "test". Ma nota anche che, nello sviluppo di applicazioni nel mondo reale, è più probabile che tu abbia un server Neo4J completo in esecuzione.

Se vogliamo utilizzare il server incorporato, dobbiamo anche aggiungere la dipendenza:

 org.neo4j neo4j-ogm-embedded-driver 3.1.2 

Le dipendenze spring-data-neo4j, neo4j-ogm-test e neo4j-ogm-embedded-driver sono disponibili su Maven Central.

3. Configurazione Neo4Jj

La configurazione di Neo4j è molto semplice e definisce l'impostazione di connessione per l'applicazione per connettersi al server. Simile alla maggior parte degli altri moduli Spring Data, questa è una configurazione Spring che può essere definita come configurazione XML o Java.

In questo tutorial, useremo solo la configurazione basata su Java:

public static final String URL = System.getenv("NEO4J_URL") != null ? System.getenv("NEO4J_URL") : "//neo4j:[email protected]:7474"; @Bean public org.neo4j.ogm.config.Configuration getConfiguration() { return new Builder().uri(URL).build(); } @Bean public SessionFactory getSessionFactory() { return new SessionFactory(getConfiguration(), "com.baeldung.spring.data.neo4j.domain"); } @Bean public Neo4jTransactionManager transactionManager() { return new Neo4jTransactionManager(getSessionFactory()); }

Come accennato in precedenza, la configurazione è semplice e contiene solo due impostazioni. Primo: SessionFactory fa riferimento ai modelli che abbiamo creato per rappresentare gli oggetti dati. Quindi, le proprietà di connessione con gli endpoint del server e le credenziali di accesso.

Neo4j dedurrà la classe del driver in base al protocollo dell'URI, nel nostro caso "http".

Si noti che in questo esempio, le proprietà relative alla connessione sono configurate direttamente sul server; tuttavia, in un'applicazione di produzione, questi dovrebbero essere adeguatamente esternalizzati e far parte della configurazione standard del progetto.

4. Archivi Neo4j

In linea con il framework Spring Data, Neo4j supporta il comportamento di astrazione del repository Spring Data. Ciò significa che l'accesso al meccanismo persistente sottostante è astratto nel Neo4jRepository integrato in cui un progetto può estenderlo direttamente e utilizzare le operazioni fornite immediatamente.

I repository sono estensibili mediante metodi finder annotati, denominati o derivati. Anche il supporto per Spring Data I repository Neo4j sono basati su Neo4jTemplate , quindi la funzionalità sottostante è identica.

4.1. Creazione di MovieRepository e PersonRepository

Usiamo due repository in questo tutorial per la persistenza dei dati:

@Repository public interface MovieRepository extends Neo4jRepository { Movie findByTitle(@Param("title") String title); @Query("MATCH (m:Movie) WHERE m.title =~ ('(?i).*'+{title}+'.*') RETURN m") Collection findByTitleContaining(@Param("title") String title); @Query("MATCH (m:Movie)<-[:ACTED_IN]-(a:Person) RETURN m.title as movie, collect(a.name) as cast LIMIT {limit}") List graph(@Param("limit") int limit); } 

Come puoi, il repository contiene alcune operazioni personalizzate oltre a quelle standard ereditate dalla classe base.

Successivamente abbiamo il PersonRepository più semplice , che ha solo le operazioni standard:

@Repository public interface PersonRepository extends Neo4jRepository  { // }

Potresti aver già notato che PersonRepository è solo l'interfaccia standard di Spring Data. Questo perché, in questo semplice esempio, è quasi sufficiente utilizzare le operazioni integrate fondamentalmente poiché il nostro set di operazioni è correlato all'entità Movie . Tuttavia è sempre possibile aggiungere qui operazioni personalizzate che possono racchiudere operazioni integrate singole / multiple.

4.2. Configurazione dei repository Neo4j

Come passaggio successivo, dobbiamo far conoscere a Spring il repository pertinente indicandolo nella classe Neo4jConfiguration creata nella sezione 3:

@Configuration @ComponentScan("com.baeldung.spring.data.neo4j") @EnableNeo4jRepositories( basePackages = "com.baeldung.spring.data.neo4j.repository") public class MovieDatabaseNeo4jConfiguration { // }

5. Il modello di dati completo

Abbiamo già iniziato a esaminare il modello di dati, quindi ora spieghiamo tutto: il film completo , il ruolo e la persona . L' entità Persona fa riferimento all'entità Film tramite la relazione Ruolo .

@NodeEntity public class Movie { @Id @GeneratedValue Long id; private String title; private int released; private String tagline; @Relationship(type="ACTED_IN", direction = Relationship.INCOMING) private List roles; // standard constructor, getters and setters }

Nota come abbiamo annotato Movie con @NodeEntity per indicare che questa classe è mappata direttamente a un nodo in Neo4j.

@JsonIdentityInfo(generator=JSOGGenerator.class) @NodeEntity public class Person { @Id @GeneratedValue Long id; private String name; private int born; @Relationship(type = "ACTED_IN") private List movies; // standard constructor, getters and setters } @JsonIdentityInfo(generator=JSOGGenerator.class) @RelationshipEntity(type = "ACTED_IN") public class Role { @Id @GeneratedValue Long id; private Collection roles; @StartNode private Person person; @EndNode private Movie movie; // standard constructor, getters and setters }

Ovviamente, queste ultime due classi sono annotate in modo simile e il riferimento a -movies - collega la classe Person alla classe Movie tramite la relazione “ACTED_IN”.

6. Accesso ai dati tramite MovieRepository

6.1. Salvataggio di un nuovo oggetto filmato

Salviamo alcuni dati, prima un nuovo film, poi una persona e ovviamente un ruolo, inclusi tutti i dati di relazione che abbiamo:

Movie italianJob = new Movie(); italianJob.setTitle("The Italian Job"); italianJob.setReleased(1999); movieRepository.save(italianJob); Person mark = new Person(); mark.setName("Mark Wahlberg"); personRepository.save(mark); Role charlie = new Role(); charlie.setMovie(italianJob); charlie.setPerson(mark); Collection roleNames = new HashSet(); roleNames.add("Charlie Croker"); charlie.setRoles(roleNames); List roles = new ArrayList(); roles.add(charlie); italianJob.setRoles(roles); movieRepository.save(italianJob);

6.2. Recupero di un oggetto filmato esistente per titolo

Verifichiamo ora il filmato inserito recuperandolo utilizzando il titolo definito che è un'operazione personalizzata:

Movie result = movieRepository.findByTitle(title);

6.3. Recupero di un oggetto filmato esistente da una parte del titolo

È possibile cercare per cercare un film esistente utilizzando una parte del titolo:

Collection result = movieRepository.findByTitleContaining("Italian");

6.4. Recupero di tutti i film

Tutti i film possono essere recuperati una volta e possono essere controllati per il conteggio corretto:

Collection result = (Collection) movieRepository.findAll();

Tuttavia esistono numerosi metodi di ricerca forniti con un comportamento predefinito utili per i requisiti doganali e non tutti sono descritti qui.

6.5. Contare gli oggetti filmato esistenti

Dopo aver inserito diversi oggetti filmato, possiamo uscire dal conteggio dei filmati:

long movieCount = movieRepository.count();

6.6. Eliminazione di un film esistente

movieRepository.delete(movieRepository.findByTitle("The Italian Job"));

Dopo aver eliminato il filmato inserito, possiamo cercare l'oggetto filmato e verificare che il risultato sia nullo:

assertNull(movieRepository.findByTitle("The Italian Job"));

6.7. Elimina tutti i dati inseriti

È possibile eliminare tutti gli elementi presenti nel database rendendo vuoto il database:

movieRepository.deleteAll();

Il risultato di questa operazione rimuove rapidamente tutti i dati da una tabella.

7. Conclusione

In questo tutorial, abbiamo esaminato le basi di Spring Data Neo4j utilizzando un esempio molto semplice.

Tuttavia Neo4j è in grado di soddisfare applicazioni molto avanzate e complesse con un enorme insieme di relazioni e reti. E Spring Data Neo4j offre anche funzionalità avanzate per mappare le classi di entità annotate al database di Neo4j Graph.

L'implementazione dei frammenti di codice e degli esempi sopra riportati può essere trovata nel progetto GitHub: questo è un progetto basato su Maven, quindi dovrebbe essere facile da importare ed eseguire così com'è.