Spring Data Neo4jの概要
1. 概要
この記事は、人気のあるグラフデータベースであるan introduction to Spring Data Neo4jです。
Spring Data Neo4jは、Neo4jグラフデータベースのPOJOベースの開発を可能にし、コアAPI使用のためのテンプレートクラスなどのSpringの使い慣れたコンセプトを使用し、注釈ベースのプログラミングモデルを提供します。
また、多くの開発者は、Neo4jが実際に特定のニーズに適しているかどうかを本当に知りません。 Stackoverflowのa solid overviewで、Neo4jを使用する理由と長所と短所について説明します。
2. Mavenの依存関係
まず、pom.xml.でSpring DataNeo4jの依存関係を宣言します。SpringDataNeo4jには、以下のSpringモジュールも必要です。
org.springframework.data
spring-data-neo4j
5.0.1.RELEASE
org.neo4j
neo4j-ogm-test
3.1.2
test
これらの依存関係には、テストに必要なモジュールも含まれます。
最後の依存関係のスコープは「テスト」であることに注意してください。 ただし、実際のアプリケーション開発では、完全なNeo4Jサーバーが実行されている可能性が高いことにも注意してください。
組み込みサーバーを使用する場合は、依存関係も追加する必要があります。
org.neo4j
neo4j-ogm-embedded-driver
3.1.2
spring-data-neo4j、neo4j-ogm-test、およびneo4j-ogm-embedded-driverの依存関係は、MavenCentralで利用できます。
3. Neo4Jj構成
Neo4jの設定は非常に単純で、アプリケーションがサーバーに接続するための接続設定を定義します。 他のほとんどのスプリングデータモジュールと同様に、これはXMLまたはJava構成として定義できるスプリング構成です。
このチュートリアルでは、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());
}
上記のように、構成は単純で、2つの設定のみが含まれています。 最初–データオブジェクトを表すために作成したモデルを参照するSessionFactory is。 次に、サーバーエンドポイントおよびアクセス資格情報との接続プロパティ。
Neo4jは、URIのプロトコル(この例では「http」)に基づいてドライバークラスを推測します。
この例では、接続関連のプロパティがサーバーに直接設定されていることに注意してください。ただし、本番アプリケーションでは、これらは適切に外部化され、プロジェクトの標準構成の一部である必要があります。
4. Neo4jリポジトリ
Neo4jは、Spring Dataフレームワークと連携して、Spring Dataリポジトリの抽象化動作をサポートしています。 つまり、基盤となる永続メカニズムへのアクセスは、組み込みのNeo4jRepositoryに抽象化されており、プロジェクトはそれを直接拡張して、提供されている操作をすぐに使用できます。
リポジトリは、注釈付き、名前付き、または派生したファインダメソッドによって拡張可能です。 Spring Data Neo4jリポジトリのサポートもNeo4jTemplateに基づいているため、基盤となる機能は同じです。
4.1. MovieRepositoryとPersonRepositoryの作成
このチュートリアルでは、データの永続化のために2つのリポジトリを使用します。
@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
可能な限り、リポジトリには、基本クラスから継承された標準的な操作だけでなく、いくつかのカスタム操作が含まれています。
次に、より単純なPersonRepositoryがあります。これは、標準の操作だけです。
@Repository
public interface PersonRepository extends Neo4jRepository {
//
}
PersonRepositoryが単なる標準のSpringDataインターフェースであることにすでに気付いているかもしれません。 これは、この単純な例では、操作セットがMovieエンティティに関連しているため、基本的に組み込み操作を使用するだけでほぼ十分であるためです。 ただし、ここにカスタム操作をいつでも追加でき、単一または複数の組み込み操作をラップできます。
4.2. Neo4jRepositoriesの構成
次のステップとして、セクション3で作成したNeo4jConfigurationクラスでそれを示す関連リポジトリをSpringに通知する必要があります。
@Configuration
@ComponentScan("com.example.spring.data.neo4j")
@EnableNeo4jRepositories(
basePackages = "com.example.spring.data.neo4j.repository")
public class MovieDatabaseNeo4jConfiguration {
//
}
5. 完全なデータモデル
すでにデータモデルを検討し始めたので、今度はすべてをレイアウトしましょう–完全なMovie, RoleとPerson。 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 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 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
}
もちろん、これらの最後の2つのクラスにも同様の注釈が付けられ、-movies–参照は、「ACTED_IN」関係によってPersonをMovieクラスにリンクしています。
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 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. タイトルによる既存の映画オブジェクトの取得
次に、カスタム操作である定義済みのタイトルを使用して、挿入されたムービーを取得して確認します。
Movie result = movieRepository.findByTitle(title);
6.3. タイトルの一部による既存の映画オブジェクトの取得
タイトルの一部を使用して、既存の映画を検索することができます。
Collection result = movieRepository.findByTitleContaining("Italian");
6.4. すべての映画を取得する
すべての映画を一度取得して、正しいカウントを確認できます。
Collection result = (Collection) movieRepository.findAll();
ただし、税関の要件に役立つデフォルトの動作を備えた多数のfindメソッドがあり、すべてがここで説明されているわけではありません。
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. 結論
このチュートリアルでは、非常に簡単な例を使用して、Spring Data Neo4jの基本について説明しました。
ただし、Neo4jは、膨大な関係とネットワークを持つ非常に高度で複雑なアプリケーションに対応できます。 また、Spring Data Neo4jは、注釈付きエンティティクラスをNeo4jグラフデータベースにマッピングする高度な機能も提供します。
上記のコードスニペットと例の実装はthe GitHub projectにあります。これはMavenベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。