Einführung in Spring Data Neo4j

Einführung in Spring Data Neo4j

1. Überblick

Dieser Artikel istan introduction to Spring Data Neo4j, die beliebte Grafikdatenbank.

Spring Data Neo4j ermöglicht die POJO-basierte Entwicklung für die Neo4j-Graph-Datenbank und verwendet bekannte Spring-Konzepte wie Vorlagenklassen für die Verwendung der Kern-API sowie ein auf Anmerkungen basierendes Programmiermodell.

Außerdem wissen viele Entwickler nicht genau, ob Neo4j tatsächlich gut zu ihren spezifischen Anforderungen passt. Ina solid overviewzu Stackoverflow wird erläutert, warum Neo4j verwendet wird und welche Vor- und Nachteile es gibt.

2. Maven-Abhängigkeiten

Beginnen wir mit der Deklaration der Spring Data Neo4j-Abhängigkeiten inpom.xml. Die unten genannten Spring-Module sind auch für Spring Data Neo4j erforderlich:


    org.springframework.data
    spring-data-neo4j
    5.0.1.RELEASE


    org.neo4j
    neo4j-ogm-test
    3.1.2
    test

Diese Abhängigkeiten umfassen auch die erforderlichen Module zum Testen.

Beachten Sie, dass die letzte Abhängigkeit als "Test" bezeichnet wird. Beachten Sie jedoch auch, dass in einer realen Anwendungsentwicklung mit größerer Wahrscheinlichkeit ein vollständiger Neo4J-Server ausgeführt wird.

Wenn wir den eingebetteten Server verwenden möchten, müssen wir auch die Abhängigkeit hinzufügen:


    org.neo4j
    neo4j-ogm-embedded-driver
    3.1.2

Die Abhängigkeitenspring-data-neo4j,neo4j-ogm-test undneo4j-ogm-embedded-driver sind in Maven Central verfügbar.

3. Neo4Jj Konfiguration

Die Neo4j-Konfiguration ist sehr einfach und definiert die Verbindungseinstellung für die Anwendung, um eine Verbindung zum Server herzustellen. Ähnlich wie die meisten anderen Federdatenmodule ist dies eine Federkonfiguration, die als XML- oder Java-Konfiguration definiert werden kann.

In diesem Tutorial verwenden wir nur die Java-basierte Konfiguration:

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

Wie oben erwähnt, ist die Konfiguration einfach und enthält nur zwei Einstellungen. Erstens - dieSessionFactory is, die auf die Modelle verweisen, die wir zur Darstellung der Datenobjekte erstellt haben. Anschließend werden die Verbindungseigenschaften mit den Serverendpunkten und die Zugangsdaten angezeigt.

Neo4j leitet die Treiberklasse basierend auf dem Protokoll der URI ab, in unserem Fall "http".

Beachten Sie, dass in diesem Beispiel die verbindungsbezogenen Eigenschaften direkt auf dem Server konfiguriert werden. In einer Produktionsanwendung sollten diese jedoch ordnungsgemäß externalisiert werden und Teil der Standardkonfiguration des Projekts sein.

4. Neo4j-Repositorys

In Übereinstimmung mit dem Spring Data Framework unterstützt Neo4j das Abstraktionsverhalten des Spring Data Repository. Das bedeutet, dass der Zugriff auf den zugrunde liegenden persistenten Mechanismus in den eingebautenNeo4jRepository abstrahiert wird, wo ein Projekt ihn direkt erweitern und die bereitgestellten Operationen sofort verwenden kann.

Die Repositorys können durch kommentierte, benannte oder abgeleitete Finder-Methoden erweitert werden. Die Unterstützung für Spring Data Neo4j-Repositorys basiert ebenfalls aufNeo4jTemplate, sodass die zugrunde liegende Funktionalität identisch ist.

4.1. Erstellen derMovieRepository &PersonRepository

In diesem Lernprogramm werden zwei Repositorys für die Datenpersistenz verwendet:

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

Wie Sie können, enthält das Repository einige benutzerdefinierte Vorgänge sowie die Standardvorgänge, die von der Basisklasse geerbt wurden.

Als nächstes haben wir die einfacherenPersonRepository, die nur die Standardoperationen haben:

@Repository
public interface PersonRepository extends Neo4jRepository  {
    //
}

Möglicherweise haben Sie bereits bemerkt, dassPersonRepository nur die Standardschnittstelle für Spring Data ist. Dies liegt daran, dass es in diesem einfachen Beispiel fast ausreichend ist, die eingebauten Operationen grundsätzlich zu verwenden, da unser Operationssatz mit der EntitätMoviezusammenhängt. Sie können hier jedoch jederzeit benutzerdefinierte Operationen hinzufügen, die einzelne / mehrere eingebaute Operationen einschließen können.

4.2. Neo4jRepositorieskonfigurieren s

Als nächsten Schritt müssen wir Spring das relevante Repository mitteilen, das es in der in Abschnitt 3 erstellten KlasseNeo4jConfigurationangibt:

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

5. Das vollständige Datenmodell

Wir haben bereits begonnen, uns das Datenmodell anzusehen. Lassen Sie uns nun alles darlegen - die vollenMovie, Role undPerson. Die EntitätPersonverweist über die BeziehungRoleauf die EntitätMovie.

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

Beachten Sie, wie wirMovie mit@NodeEntity kommentiert haben, um anzuzeigen, dass diese Klasse direkt einem Knoten in Neo4j zugeordnet ist.

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

Natürlich sind diese letzten Klassen ähnlich kommentiert, und die Referenz von -moviesverknüpftPerson mitMovie Klasse durch die Beziehung "ACTED_IN".

6. Datenzugriff mit MovieRepository

6.1. Speichern eines neuen Filmobjekts

Speichern wir einige Daten - zuerst einen neuen Film, dann eine Person und natürlich eine Rolle - einschließlich aller Beziehungsdaten, die wir ebenfalls haben:

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. Abrufen eines vorhandenen Filmobjekts nach Titel

Überprüfen Sie nun den eingefügten Film, indem Sie ihn mit dem definierten Titel abrufen. Dies ist eine benutzerdefinierte Operation:

Movie result = movieRepository.findByTitle(title);

6.3. Abrufen eines vorhandenen Filmobjekts durch einen Teil des Titels

Es ist möglich, nach einem Teil des Titels zu suchen, um nach einem vorhandenen Film zu suchen:

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

6.4. Alle Filme abrufen

Alle Filme können einmal abgerufen und auf die richtige Anzahl überprüft werden:

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

Es gibt jedoch eine Reihe von Suchmethoden mit Standardverhalten, die für Zollanforderungen nützlich sind, und nicht alle werden hier beschrieben.

6.5. Zählen Sie die vorhandenen Filmobjekte

Nachdem Sie mehrere Filmobjekte eingefügt haben, können Sie die Filmanzahl verlassen:

long movieCount = movieRepository.count();

6.6. Vorhandenen Film löschen

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

Nach dem Löschen des eingefügten Films können wir nach dem Filmobjekt suchen und sicherstellen, dass das Ergebnis null ist:

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

6.7. Alle eingefügten Daten löschen

Es ist möglich, alle Elemente in der Datenbank zu löschen, wodurch die Datenbank leer wird:

movieRepository.deleteAll();

Das Ergebnis dieser Operation entfernt schnell alle Daten aus einer Tabelle.

7. Fazit

In diesem Tutorial haben wir die Grundlagen von Spring Data Neo4j anhand eines sehr einfachen Beispiels erläutert.

Neo4j ist jedoch in der Lage, sehr fortschrittliche und komplexe Anwendungen mit einer Vielzahl von Beziehungen und Netzwerken zu bedienen. Außerdem bietet Spring Data Neo4j erweiterte Funktionen zum Zuordnen von mit Anmerkungen versehenen Entitätsklassen zur Neo4j-Graphendatenbank.

Die Implementierung der obigen Codefragmente und Beispiele finden Sie inthe GitHub project - dies ist ein Maven-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein, wie es ist.