Neo4j로 데이터 액세스
Neo4j의 NoSQL 그래프 기반 데이터 저장소를 사용하여 내장된 Neo4j 서버를 구축하고 엔터티와 관계를 저장하고 쿼리를 개발합니다.
필요한 것
약 15분
좋아하는 텍스트 편집기 또는 IDE
JDK 1.8 이상
Gradle 4 이상 또는 Maven 3.2 이상
코드를 IDE로 바로 가져올 수도 있습니다.
Spring Initializr로 시작하기
이 사전 초기화된 프로젝트 를 사용 하고 생성을 클릭하여 ZIP 파일을 다운로드할 수 있습니다. 이 프로젝트는 이 튜토리얼의 예제에 맞게 구성되었습니다.
프로젝트를 수동으로 초기화하려면:
https://start.spring.io 로 이동합니다 . 이 서비스는 애플리케이션에 필요한 모든 종속성을 가져오고 대부분의 설정을 자동으로 수행합니다.
Gradle 또는 Maven과 사용하려는 언어를 선택합니다. 이 가이드에서는 Java를 선택했다고 가정합니다.
종속성 을 클릭 하고 Spring Data Neo4j 를 선택하십시오 .
생성 을 클릭 합니다.
선택 사항으로 구성된 웹 응용 프로그램의 아카이브인 결과 ZIP 파일을 다운로드합니다.
IDE에 Spring Initializr 통합이 있는 경우 IDE에서 이 프로세스를 완료할 수 있습니다. |
Github에서 프로젝트를 분기하여 IDE 또는 다른 편집기에서 열 수도 있습니다. |
Neo4j 서버 세우기
이 애플리케이션을 빌드하기 전에 Neo4j 서버를 설정해야 합니다.
Neo4j에는 무료로 설치할 수 있는 오픈 소스 서버가 있습니다.
Homebrew가 설치된 Mac에서 다음 명령을 실행합니다.
설치가 완료되면 다음 명령을 실행하여 기본 설정으로 시작합니다.
다음과 유사한 출력이 표시되어야 합니다.
Neo4j를 시작합니다.
neo4j(pid 96416)를 시작했습니다. 기본적으로 http://localhost:7474/에서 사용할 수 있습니다.
서버가 준비될 때까지 잠시 지연될 수 있습니다.
현재 상태는 /usr/local/Cellar/neo4j/3.0.6/libexec/logs/neo4j.log를 참조하십시오.
기본적으로 Neo4j의 사용자 이름과 비밀번호는 neo4j
및 neo4j
입니다. 그러나 새 계정 비밀번호를 변경해야 합니다. 이렇게 하려면 다음 명령을 실행합니다.
curl -v -u neo4j:neo4j POST localhost:7474/user/neo4j/password -H "콘텐츠 유형: 애플리케이션/json" -d "{\"비밀번호\":\"비밀\"}"
이렇게 하면 비밀번호가 neo4j
에서 secret
— 프로덕션에서 하지 말아야 할 작업으로 변경됩니다! 이 단계가 완료되면 이 가이드의 나머지 부분을 실행할 준비가 된 것입니다.
단순 엔터티 정의
Neo4j는 엔티티와 이들의 관계를 캡처하며 두 측면 모두 동일한 중요성을 갖습니다. 각 사람에 대한 기록을 저장하는 시스템을 모델링한다고 상상해 보십시오. 그러나 한 사람의 동료도 추적하려고 합니다( teammates
이 예에서는). Spring Data Neo4j를 사용하면 다음 목록( src/main/java/com/example/accessingdataneo4j/Person.java
)에서 볼 수 있듯이 몇 가지 간단한 주석으로 모든 것을 캡처할 수 있습니다.
package com.example.accessingdataneo4j;
import java.util.Collections;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.Node;
import org.springframework.data.neo4j.core.schema.Property;
import org.springframework.data.neo4j.core.schema.Relationship;
import org.springframework.data.neo4j.core.schema.GeneratedValue;
@Node
public class Person {
@Id @GeneratedValue private Long id;
private String name;
private Person() {
// Empty constructor required as of Neo4j API 2.0.5
};
public Person(String name) {
this.name = name;
}
/**
* Neo4j doesn't REALLY have bi-directional relationships. It just means when querying
* to ignore the direction of the relationship.
* https://dzone.com/articles/modelling-data-neo4j
*/
@Relationship(type = "TEAMMATE")
public Set<Person> teammates;
public void worksWith(Person person) {
if (teammates == null) {
teammates = new HashSet<>();
}
teammates.add(person);
}
public String toString() {
return this.name + "'s teammates => "
+ Optional.ofNullable(this.teammates).orElse(
Collections.emptySet()).stream()
.map(Person::getName)
.collect(Collectors.toList());
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
여기에 Person
속성이 하나만 있는 클래스가 있습니다 name
. .
Person
클래스에는 로 주석이 달려 있습니다 @NodeEntity
. Neo4j가 저장하면 새 노드가 생성됩니다. 이 클래스에도 id
표시 가 @GraphId
있습니다. Neo4j는 @GraphId
내부적으로 데이터를 추적하는 데 사용합니다.
다음으로 중요한 부분은 의 집합입니다 teammates
. 간단 Set<Person>
하지만 로 표시됩니다 @Relationship
. 이는 이 집합의 모든 구성원이 별도의 Person
노드로도 존재할 것으로 예상된다는 것을 의미합니다. 방향이 로 설정되는 방법에 유의하십시오 UNDIRECTED
. 즉, 관계를 쿼리할 때 TEAMMATE
Spring Data Neo4j는 관계의 방향을 무시합니다.
이 worksWith()
방법을 사용하면 사람들을 쉽게 연결할 수 있습니다.
toString()
마지막으로 그 사람의 이름과 그 사람의 동료를 인쇄 하는 편리한 방법이 있습니다.
간단한 쿼리 만들기
Spring Data Neo4j는 Neo4j에 데이터를 저장하는 데 중점을 둡니다. 그러나 쿼리 파생 기능을 포함하여 Spring Data Commons 프로젝트의 기능을 상속합니다. 기본적으로 Neo4j의 쿼리 언어를 배울 필요는 없습니다. 대신 몇 가지 메서드를 작성하고 쿼리를 작성할 수 있습니다.
이것이 어떻게 작동하는지 보려면 Person
노드를 쿼리하는 인터페이스를 만드십시오. 다음 목록( src/main/java/com/example/accessingdataneo4j/PersonRepository.java
)은 이러한 쿼리를 보여줍니다.
package com.example.accessingdataneo4j;
import java.util.List;
import org.springframework.data.neo4j.repository.Neo4jRepository;
public interface PersonRepository extends Neo4jRepository<Person, Long> {
Person findByName(String name);
List<Person> findByTeammatesName(String name);
}
PersonRepository
인터페이스를 확장하고 Neo4jRepository
작동하는 유형을 연결합니다 Person
. 이 인터페이스는 표준 CRUD(만들기, 읽기, 업데이트 및 삭제) 작업을 비롯한 많은 작업과 함께 제공됩니다.
그러나 메서드 서명을 선언하여 다른 쿼리를 정의할 수 있습니다. 이 경우 findByName
유형의 노드를 Person
찾고 에서 일치하는 노드를 찾는 를 추가했습니다 name
. 또한 노드 findByTeammatesName
를 찾고 필드의 각 항목을 드릴하고 팀원의 .Person``teammates``name
Neo4j 접근 권한
Neo4j Community Edition에 액세스하려면 자격 증명이 필요합니다. src/main/resources/application.properties
다음 목록과 같이 몇 가지 속성( 에서)을 설정하여 이러한 자격 증명을 구성할 수 있습니다 .
spring.neo4j.uri=bolt://localhost:7687
spring.data.neo4j.username=neo4j
spring.data.neo4j.password=비밀
여기에는 기본 사용자 이름( neo4j
)과 앞에서 선택한 새로 설정한 암호( secret
)가 포함됩니다.
이것을 제자리에 연결하면 어떻게 보이는지 확인할 수 있습니다!
애플리케이션 클래스 생성
Spring Initializr는 애플리케이션을 위한 간단한 클래스를 생성합니다. 다음 목록은 Initializr이 이 예제(에서 src/main/java/com/example/accessingdataneo4j/AccessingDataNeo4jApplication.java
)를 위해 생성한 클래스를 보여줍니다.
package com.example.accessingdataneo4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AccessingDataNeo4jApplication {
public static void main(String[] args) {
SpringApplication.run(AccessingDataNeo4jApplication.class, args);
}
}
@SpringBootApplication
다음을 모두 추가하는 편의 주석입니다.
@Configuration
: 애플리케이션 컨텍스트에 대한 빈 정의의 소스로 클래스에 태그를 지정합니다.@EnableAutoConfiguration
: Spring Boot에 클래스 경로 설정, 기타 빈 및 다양한 속성 설정을 기반으로 빈 추가를 시작하도록 지시합니다. 예를 들어spring-webmvc
가 클래스 경로에 있는 경우 이 주석은 애플리케이션을 웹 애플리케이션으로 플래그 지정하고DispatcherServlet
.@ComponentScan
: Spring이com/example
패키지에서 다른 구성 요소, 구성 및 서비스를 찾도록 지시하여 컨트롤러를 찾도록 합니다.
이 main()
방법은 Spring Boot의 SpringApplication.run()
방법을 사용하여 애플리케이션을 시작합니다. XML이 한 줄도 없다는 사실을 눈치채셨나요? 파일 도 없습니다 web.xml
. 이 웹 애플리케이션은 100% 순수 Java이며 배관이나 인프라 구성을 처리할 필요가 없습니다.
Spring Boot는 해당 리포지토리가 클래스의 동일한 패키지(또는 하위 패키지)에 포함되어 있는 한 자동으로 처리합니다 @SpringBootApplication
. @EnableNeo4jRepositories
등록 프로세스를 더 자세히 제어하려면 주석 을 사용할 수 있습니다 .
기본적 @EnableNeo4jRepositories 으로 Spring Data의 저장소 인터페이스 중 하나를 확장하는 모든 인터페이스에 대해 현재 패키지를 스캔합니다. basePackageClasses=MyRepository.class 프로젝트 레이아웃에 여러 프로젝트가 있고 저장소를 찾지 못하는 경우 이를 사용하여 Spring Data Neo4j가 유형별로 다른 루트 패키지를 스캔하도록 안전하게 지시할 수 있습니다 . |
로깅 출력이 표시됩니다. 서비스는 몇 초 안에 시작되어 실행되어야 합니다.
PersonRepository
이제 이전에 정의한 인스턴스를 autowire합니다 . Spring Data Neo4j는 해당 인터페이스를 동적으로 구현하고 인터페이스의 의무를 충족하기 위해 필요한 쿼리 코드를 플러그인합니다.
이 main
메서드는 Spring Boot SpringApplication.run()
를 사용하여 애플리케이션을 시작하고 CommandLineRunner
관계를 구축하는 호출을 호출합니다.
이 경우에는 Person
Greg, Roy 및 Craig의 세 가지 로컬 인스턴스를 작성합니다. 처음에는 메모리에만 존재합니다. 아무도 (아직) 누구와도 팀 동료가 아닙니다.
처음에 Greg를 찾고 Roy 및 Craig와 함께 일하고 있음을 표시한 다음 다시 그를 유지합니다. 팀원 관계가 UNDIRECTED
(즉, 양방향)로 표시되었음을 기억하십시오. 즉, Roy와 Craig도 업데이트되었습니다.
그렇기 때문에 Roy를 업데이트해야 할 때입니다. 먼저 Neo4j에서 해당 레코드를 가져오는 것이 중요합니다. 목록에 Craig를 추가하기 전에 Roy의 팀원에 대한 최신 상태가 필요합니다.
Craig를 가져오고 관계를 추가하는 코드가 없는 이유는 무엇입니까? 당신은 이미 그것을 가지고 있기 때문에! Greg는 이전에 Craig를 팀원으로 태그했으며 Roy도 마찬가지였습니다. 즉, Craig의 관계를 다시 업데이트할 필요가 없습니다. 각 팀 구성원에 대해 반복하고 해당 정보를 콘솔에 인쇄할 때 이를 볼 수 있습니다.
마지막으로, "누가 누구와 함께 일합니까?"라는 질문에 답하면서 뒤를 돌아보는 다른 쿼리를 확인하십시오.
다음 목록은 완성된 AccessingDataNeo4jApplication
클래스(at src/main/java/com/example/accessingdataneo4j/AccessingDataNeo4jApplication.java
)를 보여줍니다.
package com.example.accessingdataneo4j;
import java.util.Arrays;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
@SpringBootApplication
@EnableNeo4jRepositories
public class AccessingDataNeo4jApplication {
private final static Logger log = LoggerFactory.getLogger(AccessingDataNeo4jApplication.class);
public static void main(String[] args) throws Exception {
SpringApplication.run(AccessingDataNeo4jApplication.class, args);
System.exit(0);
}
@Bean
CommandLineRunner demo(PersonRepository personRepository) {
return args -> {
personRepository.deleteAll();
Person greg = new Person("Greg");
Person roy = new Person("Roy");
Person craig = new Person("Craig");
List<Person> team = Arrays.asList(greg, roy, craig);
log.info("Before linking up with Neo4j...");
team.stream().forEach(person -> log.info("\t" + person.toString()));
personRepository.save(greg);
personRepository.save(roy);
personRepository.save(craig);
greg = personRepository.findByName(greg.getName());
greg.worksWith(roy);
greg.worksWith(craig);
personRepository.save(greg);
roy = personRepository.findByName(roy.getName());
roy.worksWith(craig);
// We already know that roy works with greg
personRepository.save(roy);
// We already know craig works with roy and greg
log.info("Lookup each person by name...");
team.stream().forEach(person -> log.info(
"\t" + personRepository.findByName(person.getName()).toString()));
List<Person> teammates = personRepository.findByTeammatesName(greg.getName());
log.info("The following have Greg as a teammate...");
teammates.stream().forEach(person -> log.info("\t" + person.getName()));
};
}
}
실행 가능한 JAR 빌드
Gradle 또는 Maven을 사용하여 명령줄에서 애플리케이션을 실행할 수 있습니다. 필요한 모든 종속성, 클래스 및 리소스가 포함된 단일 실행 가능한 JAR 파일을 빌드하고 실행할 수도 있습니다. 실행 가능한 jar를 빌드하면 개발 수명 주기 전반에 걸쳐 다양한 환경 등에서 서비스를 애플리케이션으로 쉽게 제공, 버전 지정 및 배포할 수 있습니다.
Gradle을 사용한다면 ./gradlew bootRun
. 또는 다음과 같이 JAR 파일을 사용하여 빌드한 ./gradlew build
후 실행할 수 있습니다.
자바 -jar 빌드/libs/gs-accessing-data-neo4j-0.1.0.jar
Maven을 사용한다면 ./mvnw spring-boot:run
. 또는 다음과 같이 JAR 파일을 빌드한 ./mvnw clean package
다음 JAR 파일을 실행할 수 있습니다.
자바 -jar 대상/gs-accessing-data-neo4j-0.1.0.jar
다음 목록과 유사한 내용이 표시되어야 합니다(쿼리와 같은 다른 항목도 포함).
Neo4j와 연동하기 전에...
그렉의 팀원 => []
로이의 동료 => []
크레이그의 동료 => []
각 사람의 이름을 검색하십시오 ...
그렉의 팀원 => [로이, 크레이그]
로이의 동료 => [그렉, 크레이그]
크레이그의 동료 => [로이, 그렉]
출력에서 (초기) 아무도 어떤 관계로 연결되어 있지 않다는 것을 알 수 있습니다. 그런 다음 사람을 추가하면 함께 묶입니다. 마지막으로 팀원을 기준으로 사람을 조회하는 편리한 쿼리를 볼 수 있습니다.
요약
축하합니다! 내장된 Neo4j 서버를 설정하고 몇 가지 간단한 관련 엔터티를 저장하고 몇 가지 빠른 쿼리를 개발했습니다.
[광고] STEEM 개발자 커뮤니티에 참여 하시면, 다양한 혜택을 받을 수 있습니다.