Introduction à Spring Data Neo4j

1. Vue d'ensemble

Cet article est une introduction à Spring Data Neo4j , la base de données de graphes populaire.

Spring Data Neo4j permet le développement basé sur POJO pour la base de données Neo4j Graph et utilise des concepts Spring familiers tels que des classes de modèle pour l'utilisation de l'API principale et fournit un modèle de programmation basé sur des annotations.

De plus, beaucoup de développeurs ne savent pas vraiment si Neo4j répondra réellement à leurs besoins spécifiques; voici un bon aperçu de Stackoverflow expliquant pourquoi utiliser Neo4j et ses avantages et inconvénients.

2. Dépendances de Maven

Commençons par déclarer les dépendances Spring Data Neo4j dans le pom.xml. Les modules Spring mentionnés ci-dessous sont également requis pour Spring Data Neo4j:

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

Ces dépendances incluent également les modules requis pour les tests.

Notez que la dernière dépendance est portée comme «test». Mais notez également que, dans un développement d'application réel, vous êtes plus susceptible d'avoir un serveur Neo4J complet en cours d'exécution.

Si nous voulons utiliser le serveur embarqué, nous devons également ajouter la dépendance:

 org.neo4j neo4j-ogm-embedded-driver 3.1.2 

Les dépendances spring-data-neo4j, neo4j-ogm-test et neo4j-ogm-embedded-driver sont disponibles sur Maven Central.

3. Configuration Neo4Jj

La configuration Neo4j est très simple et définit le paramètre de connexion de l'application pour se connecter au serveur. Semblable à la plupart des autres modules de données Spring, il s'agit d'une configuration Spring qui peut être définie comme configuration XML ou Java.

Dans ce didacticiel, nous utiliserons uniquement la configuration basée sur 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()); }

Comme mentionné ci-dessus, la configuration est simple et ne contient que deux paramètres. Premièrement, la SessionFactory fait référence aux modèles que nous avons créés pour représenter les objets de données. Ensuite, les propriétés de connexion avec les points de terminaison du serveur et les informations d'identification d'accès.

Neo4j inférera la classe du pilote en fonction du protocole de l'URI, dans notre cas «http».

Veuillez noter que dans cet exemple, les propriétés liées à la connexion sont configurées directement sur le serveur; cependant, dans une application de production, ceux-ci doivent être correctement externalisés et faire partie de la configuration standard du projet.

4. Dépôts Neo4j

S'alignant sur le framework Spring Data, Neo4j prend en charge le comportement d'abstraction du référentiel Spring Data. Cela signifie que l'accès au mécanisme persistant sous-jacent est abstrait dans le Neo4jRepository intégré où un projet peut directement l'étendre et utiliser les opérations fournies prêtes à l' emploi .

Les référentiels sont extensibles par des méthodes de recherche annotées, nommées ou dérivées. La prise en charge des référentiels Spring Data Neo4j est également basée sur Neo4jTemplate , de sorte que la fonctionnalité sous-jacente est identique.

4.1. Création du MovieRepository et du PersonRepository

Nous utilisons deux référentiels dans ce didacticiel pour la persistance des données:

@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); } 

Comme vous le pouvez, le référentiel contient des opérations personnalisées ainsi que des opérations standard héritées de la classe de base.

Ensuite, nous avons le PersonRepository plus simple , qui ne contient que les opérations standard:

@Repository public interface PersonRepository extends Neo4jRepository  { // }

Vous avez peut-être déjà remarqué que PersonRepository n'est que l'interface standard de Spring Data. En effet, dans cet exemple simple, il est presque suffisant d'utiliser les opérations intégrées essentiellement car notre ensemble d'opérations est lié à l' entité Movie . Cependant, vous pouvez toujours ajouter ici des opérations personnalisées qui peuvent encapsuler des opérations intégrées simples / multiples.

4.2. Configurer les référentiels Neo4j

À l'étape suivante, nous devons informer Spring du référentiel pertinent en l'indiquant dans la classe Neo4jConfiguration créée dans la section 3:

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

5. Le modèle de données complètes

Nous avons déjà commencé à examiner le modèle de données, alors exposons maintenant tout - le film complet , le rôle et la personne . L' entité Person fait référence à l' entité Movie via la relation Role .

@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 }

Notez comment nous avons annoté Movie avec @NodeEntity pour indiquer que cette classe est directement mappée à un nœud dans 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 }

Bien sûr, ces deux dernières classes sont annotées de la même manière et la référence -movies - relie la classe Person à Movie par la relation «ACTED_IN».

6. Accès aux données à l'aide de MovieRepository

6.1. Enregistrement d'un nouvel objet film

Sauvegardons quelques données - d'abord, un nouveau film, puis une personne et bien sûr un rôle - y compris toutes les données de relation que nous avons également:

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. Récupération d'un objet vidéo existant par titre

Vérifions maintenant le film inséré en le récupérant à l'aide du titre défini qui est une opération personnalisée:

Movie result = movieRepository.findByTitle(title);

6.3. Récupération d'un objet film existant par une partie du titre

Il est possible de rechercher pour rechercher un film existant en utilisant une partie du titre:

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

6.4. Récupération de tous les films

Tous les films peuvent être récupérés une fois et peuvent être vérifiés pour le compte correct:

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

Cependant, il existe un certain nombre de méthodes de recherche fournies avec un comportement par défaut qui est utile pour les exigences douanières et toutes ne sont pas décrites ici.

6.5. Compter les objets vidéo existants

Après avoir inséré plusieurs objets de film, nous pouvons obtenir le nombre de films sortants:

long movieCount = movieRepository.count();

6.6. Suppression d'un film existant

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

Après avoir supprimé le film inséré, nous pouvons rechercher l'objet du film et vérifier que le résultat est nul:

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

6.7. Supprimer toutes les données insérées

Il est possible de supprimer tous les éléments de la base de données rendant la base de données vide:

movieRepository.deleteAll();

Le résultat de cette opération supprime rapidement toutes les données d'une table.

7. Conclusion

Dans ce tutoriel, nous avons passé en revue les bases de Spring Data Neo4j à l'aide d'un exemple très simple.

Cependant Neo4j est capable de répondre à des applications très avancées et complexes ayant un vaste ensemble de relations et de réseaux. Et Spring Data Neo4j propose également des fonctionnalités avancées pour mapper les classes d'entités annotées à la base de données de graphes Neo4j.

L'implémentation des extraits de code et des exemples ci-dessus peut être trouvée dans le projet GitHub - il s'agit d'un projet basé sur Maven, il devrait donc être facile à importer et à exécuter tel quel.