1. 概要

この記事は、人気のあるグラフデータベースであるSpring DataNeo4jの紹介です。

Spring Data Neo4jは、Neo4jグラフデータベースのPOJOベースの開発を可能にし、コアAPI使用のためのテンプレートクラスなどの使い慣れたSpringの概念を使用し、注釈ベースのプログラミングモデルを提供します。

また、多くの開発者は、Neo4jが実際に特定のニーズに適しているかどうかを本当に知りません。 ここにStackoverflowの確かな概要があり、Neo4jを使用する理由と長所と短所について説明しています。

2. Mavenの依存関係

まず、SpringDataNeo4jの依存関係を宣言することから始めましょう。 pom.xml。 下記のSpringモジュールはSpringDataNeo4jにも必要です。

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-neo4j</artifactId>
    <version>5.0.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.neo4j</groupId>
    <artifactId>neo4j-ogm-test</artifactId>
    <version>3.1.2</version>
    <scope>test</scope>
</dependency>

これらの依存関係には、テストに必要なモジュールも含まれます。

最後の依存関係は「test」としてスコープされていることに注意してください。 ただし、実際のアプリケーション開発では、完全なNeo4Jサーバーが実行されている可能性が高いことにも注意してください。

組み込みサーバーを使用する場合は、依存関係も追加する必要があります。

<dependency>
    <groupId>org.neo4j</groupId>
    <artifactId>neo4j-ogm-embedded-driver</artifactId>
    <version>3.1.2</version>
</dependency>

spring-data-neo4j neo4j-ogm-test 、およびneo4j-ogm-embedded-driverの依存関係はMavenCentralで利用できます。

3. Neo4Jj構成

Neo4jの構成は非常に単純で、アプリケーションがサーバーに接続するための接続設定を定義します。 他のほとんどのSpringデータモジュールと同様に、これはXMLまたはJava構成として定義できるSpring構成です。

このチュートリアルでは、Javaベースの構成のみを使用します。

public static final String URL = 
  System.getenv("NEO4J_URL") != null ? 
  System.getenv("NEO4J_URL") : "http://neo4j:movies@localhost: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());
}

上記のように、構成は単純で、2つの設定のみが含まれています。 まず、 SessionFactoryは、データオブジェクトを表すために作成したモデルを参照しています。 次に、サーバーエンドポイントとアクセス資格情報との接続プロパティ。

Neo4jは、URIのプロトコル(この場合は「http」)に基づいてドライバークラスを推測します。

この例では、接続関連のプロパティがサーバーに直接構成されていることに注意してください。 ただし、実稼働アプリケーションでは、これらは適切に外部化され、プロジェクトの標準構成の一部である必要があります。

4. Neo4jリポジトリ

Neo4jは、Spring Dataフレームワークと連携して、SpringDataリポジトリの抽象化動作をサポートします。 つまり、基盤となる永続メカニズムへのアクセスは、組み込みの Neo4jRepository に抽象化されており、プロジェクトはそれを直接拡張して、提供されている操作をすぐに使用できます。

リポジトリは、注釈付き、名前付き、または派生したファインダーメソッドによって拡張できます。 Spring DataNeo4jリポジトリのサポートもNeo4jTemplateに基づいているため、基盤となる機能は同じです。

4.1. の作成 MovieRepository PersonRepository

このチュートリアルでは、データの永続性のために2つのリポジトリを使用します。

@Repository
public interface MovieRepository extends Neo4jRepository<Movie, Long> {

    Movie findByTitle(@Param("title") String title);

    @Query("MATCH (m:Movie) WHERE m.title =~ ('(?i).*'+{title}+'.*') RETURN m")
    Collection<Movie> 
      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<Map<String,Object>> graph(@Param("limit") int limit);
}

可能な限り、リポジトリには、基本クラスから継承された標準操作だけでなく、いくつかのカスタム操作も含まれています。

次に、より単純な PersonRepository があります。これには、標準の操作が含まれています。

@Repository
public interface PersonRepository extends Neo4jRepository <Person, Long> {
    //
}

PersonRepositoryが単なる標準のSpringDataインターフェイスであることにお気づきかもしれません。 これは、この単純な例では、操作セットが Movie エンティティに関連しているため、基本的に組み込みの操作を使用するだけでほぼ十分であるためです。 ただし、ここにカスタム操作をいつでも追加できます。これにより、単一または複数の組み込み操作がラップされる場合があります。

4.2. Neo4jリポジトリの構成

次のステップとして、セクション3で作成したNeo4jConfigurationクラスでそれを示す関連リポジトリをSpringに通知する必要があります。

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

5. 完全なデータモデル

すでにデータモデルを検討し始めたので、今度はすべてをレイアウトしましょう–完全な映画、役割 Person エンティティは、Role関係を通じてMovieエンティティを参照します。

@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<Role> roles;

    // standard constructor, getters and setters 
}

このクラスがNeo4jのノードに直接マップされていることを示すために、Movie@NodeEntityという注釈を付けていることに注目してください。

@JsonIdentityInfo(generator=JSOGGenerator.class)
@NodeEntity
public class Person {

    @Id @GeneratedValue
    Long id;

    private String name;

    private int born;

    @Relationship(type = "ACTED_IN")
    private List<Movie> movies;

    // standard constructor, getters and setters 
}

@JsonIdentityInfo(generator=JSOGGenerator.class)
@RelationshipEntity(type = "ACTED_IN")
public class Role {

    @Id @GeneratedValue
    Long id;

    private Collection<String> roles;

    @StartNode
    private Person person;

    @EndNode
    private Movie movie;

    // standard constructor, getters and setters 
}

もちろん、これらの最後の2つのクラスにも同様の注釈が付けられ、-movies 参照は、「ACTED_IN」関係によってPersonMovieクラスにリンクしています。

6. MovieRepositoryを使用したデータアクセス

6.1. 新しいムービーオブジェクトの保存

最初に新しい映画、次に人物、そしてもちろん役割など、いくつかのデータを保存しましょう。これには、私たちが持っているすべての関係データも含まれます。

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<String> roleNames = new HashSet();
roleNames.add("Charlie Croker");
charlie.setRoles(roleNames);
List<Role> roles = new ArrayList();
roles.add(charlie);
italianJob.setRoles(roles);
movieRepository.save(italianJob);

6.2. タイトルによる既存の映画オブジェクトの取得

次に、カスタム操作である定義済みのタイトルを使用して、挿入されたムービーを取得して確認します。

Movie result = movieRepository.findByTitle(title);

6.3. タイトルの一部による既存の映画オブジェクトの取得

タイトルの一部を使用して、既存の映画を検索することができます。

Collection<Movie> result = movieRepository.findByTitleContaining("Italian");

6.4. すべての映画を取得する

すべての映画は一度取得でき、正しいカウントを確認できます。

Collection<Movie> result = (Collection<Movie>) movieRepository.findAll();

ただし、税関の要件に役立つデフォルトの動作で提供される検索メソッドは多数あり、すべてがここで説明されているわけではありません。

6.5. 既存のムービーオブジェクトを数える

いくつかのムービーオブジェクトを挿入した後、終了するムービーカウントを取得できます。

long movieCount = movieRepository.count();

6.6. 既存のムービーを削除する

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

挿入されたムービーを削除した後、ムービーオブジェクトを検索して、結果がnullであることを確認できます。

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

6.7. 挿入されたデータをすべて削除する

データベース内のすべての要素を削除して、データベースを空にすることができます。

movieRepository.deleteAll();

この操作の結果、テーブルからすべてのデータがすばやく削除されます。

7. 結論

このチュートリアルでは、非常に簡単な例を使用して、SpringDataNeo4jの基本を説明しました。

ただし、Neo4jは、膨大な関係とネットワークのセットを持つ非常に高度で複雑なアプリケーションに対応できます。 また、Spring Data Neo4jは、注釈付きエンティティクラスをNeo4jグラフデータベースにマップするための高度な機能も提供します。

上記のコードスニペットと例の実装は、 GitHubプロジェクトにあります。これはMavenベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。