Introduction à Spring Data Neo4j

Introduction à Spring Data Neo4j

1. Vue d'ensemble

Cet article estan introduction to 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 de graphes Neo4j et utilise des concepts Spring connus, 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; voicia solid overview sur Stackoverflow expliquant pourquoi utiliser Neo4j et ses avantages et inconvénients.

2. Dépendances Maven

Commençons par déclarer les dépendances Spring Data Neo4j dans lespom.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 définie 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 intégré, nous devons également ajouter la dépendance:


    org.neo4j
    neo4j-ogm-embedded-driver
    3.1.2

Les dépendancesspring-data-neo4j,neo4j-ogm-test etneo4j-ogm-embedded-driver sont disponibles sur Maven Central.

3. Configuration Neo4Jj

La configuration de Neo4j est très simple et définit les paramètres de connexion pour que l’application se connecte au serveur. Semblable à la plupart des autres modules de données à ressort, il s'agit d'une configuration à ressort pouvant être définie en tant que 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") : "http://neo4j:[email protected]:7474";

@Bean
public org.neo4j.ogm.config.Configuration getConfiguration() {
    org.neo4j.ogm.config.Configuration config = new Builder().uri(URL).build();
    return config;
}

@Bean
public SessionFactory getSessionFactory() {
    return new SessionFactory(getConfiguration(),
      "com.example.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 - lesSessionFactory is référençant les modèles que nous avons créés pour représenter les objets de données. Ensuite, les propriétés de connexion avec les noeuds finaux du serveur et les informations d'identification d'accès.

Neo4j déduira la classe de 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 la structure 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 lesNeo4jRepositoryintégrés où un projet peut directement l'étendre et utiliser les opérations fournies prêtes à l'emploi.

Les référentiels sont extensibles à l'aide de 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 surNeo4jTemplate, donc la fonctionnalité sous-jacente est identique.

4.1. Création desMovieRepository etPersonRepository

Nous utilisons deux référentiels dans ce tutoriel 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 plus simplePersonRepository, qui n'a que les opérations standard:

@Repository
public interface PersonRepository extends Neo4jRepository  {
    //
}

Vous avez peut-être déjà remarqué quePersonRepository n'est que l'interface standard de Spring Data. C'est parce que, 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 pouvant englober une ou plusieurs opérations intégrées.

4.2. Configurer Neo4jRepositories

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

@Configuration
@ComponentScan("com.example.spring.data.neo4j")
@EnableNeo4jRepositories(
  basePackages = "com.example.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 - lesMovie, Role etPerson complets. L'entitéPerson fait référence à l'entitéMovie via la relationRole.

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

Remarquez 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 reliePerson à la classeMovie 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 dont nous disposons é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 d'effectuer une recherche 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 nombre correct:

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

Toutefois, il existe un certain nombre de méthodes de recherche dotées d'un comportement par défaut qui sont utiles pour les besoins en douane 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 existant:

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 de film et vérifier que le résultat est null:

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 en la rendant 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 présenté les bases de Spring Data Neo4j en utilisant un exemple très simple.

Cependant, Neo4j est capable de prendre en charge des applications très avancées et complexes comportant un vaste ensemble de relations et de réseaux. Spring Data Neo4j offre également des fonctionnalités avancées pour mapper les classes d'entités annotées vers la base de données de graphes Neo4j.

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