原文
https://spring.io/guides/gs/accessing-data-neo4j/
直译
启动Neo4j服务器
在构建此应用程序之前,您需要设置Neo4j服务器。
Neo4j有一个可以免费安装的开源服务器:
在Mac上,只需输入:
$ brew install neo4j
有关其他选项,请访问https://neo4j.com/download/community-edition/
安装后,使用默认设置启动它:
$ neo4j start
你应该看到这样的消息:
Starting Neo4j.
Started neo4j (pid 96416). By default, it is available at http://localhost:7474/
There may be a short delay until the server is ready.
See /usr/local/Cellar/neo4j/3.0.6/libexec/logs/neo4j.log for current status.
默认情况下,Neo4j的用户名/密码为neo4j / neo4j。但是,它需要更改新的帐户密码。为此,请执行以下命令:
$ curl -v -u neo4j:neo4j -X POST localhost:7474 / user / neo4j / password -H“Content-type:application / json”-d“{\”password \“:\”secret \“}”
这会将密码从neo4j更改为secret(生产中的某些内容!)完成后,您应该已准备好运行本指南。
定义一个简单的实体
Neo4j捕获实体及其关系,两个方面同等重要。想象一下,您正在建模一个系统,您可以在其中存储每个人的记录。但是你也想跟踪一个人的同事(teammates在这个例子中)。使用Neo4j,您可以使用一些简单的注释捕获所有这些内容。
src/main/java/hello/Person.java
package hello;
import java.util.Collections;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.neo4j.ogm.annotation.GeneratedValue;
import org.neo4j.ogm.annotation.Id;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Relationship;
@NodeEntity
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", direction = Relationship.UNDIRECTED)
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,但标注为@Relationship。这意味着该集合的每个成员都应该作为单独的Person节点存在。注意方向是如何设置的UNDIRECTED。这意味着当您查询TEAMMATE关系时,Spring Data Neo4j将忽略关系的方向。
使用该worksWith()方法,您可以轻松地将人们联系在一起。
最后,您有一个方便的toString()方法来打印出该人的姓名和该人的同事。
创建简单查询
Spring Data Neo4j专注于在Neo4j中存储数据。但它继承了Spring Data Commons项目的功能,包括派生查询的能力。基本上,您不必学习Neo4j的查询语言,但可以简单地编写一些方法,并为您编写查询。
要查看其工作原理,请创建一个查询Person节点的接口。
src/main/java/hello/PersonRepository.java
package hello;
import org.springframework.data.repository.CrudRepository;
public interface PersonRepository extends CrudRepository<Person, Long> {
Person findByName(String name);
}
PersonRepository扩展GraphRepository其操作类型的接口和插头:Person。开箱即用,该界面带有许多操作,包括标准CRUD(创建 - 读取 - 更新 - 删除)操作。
但您可以通过简单地声明其方法签名来根据需要定义其他查询。在这种情况下,您添加了findByName,它搜索类型的节点Person并找到匹配的节点name。您还可以findByTeammatesName查找某个Person节点,在该teammates字段的每个条目中进行钻取,并根据队友进行匹配name。
访问Neo4j的权限
Neo4j Community Edition需要凭据才能访问它。这可以配置一些属性。
spring.data.neo4j.username=neo4j
spring.data.neo4j.password=secret
这包括默认用户名neo4j和secret我们之前选择的新设置密码。
不要在源存储库中存储真实凭据。而是使用Spring Boot的属性覆盖在运行时中配置它们。
有了这个,让我们把它连接起来看看它的样子!
创建一个Application类
在这里,您将创建一个包含所有组件的Application类。
src/main/java/hello/Application.java
package hello;
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 Application {
private final static Logger log = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
@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()));
};
}
}
@SpringBootApplication 是一个便利注释,添加了以下所有内容:
-
@Configuration 标记该类作为应用程序上下文的bean定义的来源。
-
@EnableAutoConfiguration 告诉Spring Boot开始根据类路径设置,其他bean和各种属性设置添加bean。
-
通常你会添加@EnableWebMvc一个Spring MVC应用程序,但Spring Boot会在类路径上看到spring-webmvc时自动添加它。这会将应用程序标记为Web应用程序并激活关键行为,例如设置a DispatcherServlet。
-
@ComponentScan告诉Spring在包中寻找其他组件,配置和服务hello,允许它找到控制器。
该main()方法使用Spring Boot的SpringApplication.run()方法启动应用程序。您是否注意到没有一行XML?也没有web.xml文件。此Web应用程序是100%纯Java,您无需处理配置任何管道或基础结构。
Spring Boot将自动处理这些存储库,只要它们包含在您的@SpringBootApplication类的同一个包(或子包)中。要更好地控制注册过程,可以使用@EnableNeo4jRepositories注释。
默认情况下,@EnableNeo4jRepositories将扫描当前包以查找扩展Spring Data存储库接口之一的任何接口。basePackageClasses=MyRepository.class如果您的项目布局有多个项目且找不到您的存储库,请使用它来安全地告诉Spring Data Neo4j按类型扫描不同的根软件包。
显示记录输出。该服务应在几秒钟内启动并运行。
您自动装配PersonRepository您之前定义的实例。Spring Data Neo4j将动态实现该接口,并插入所需的查询代码以满足接口的义务。
在public static void main使用Spring Boot的SpringApplication.run()启动应用程序并调用CommandLineRunner该建立的关系。
在这种情况下,你创建了三个本地Persons,Greg,Roy和Craig。最初,它们只存在于内存中。同样重要的是要注意,没有人是(任何人)的队友。
起初,你找到格雷格,并表示他与罗伊和克雷格合作,然后再次坚持他。请记住,队友关系被标记为UNDIRECTED,即双向关系。这意味着Roy和Craig也将更新。
这就是为什么当你需要更新Roy时,首先从Neo4j获取该记录至关重要。在将Craig添加到列表之前,您需要Roy的队友的最新状态。
为什么没有代码可以获取Craig并添加任何关系?因为你已经拥有了!格雷格早些时候将克雷格称为队友,罗伊也是如此。这意味着没有必要再次更新Craig的关系。您可以在迭代每个团队成员并将其信息打印到控制台时看到它。
最后,查看您向后看的其他查询,回答“谁与谁合作?”的问题。
构建可执行的JAR
您可以使用Gradle或Maven从命令行运行该应用程序。或者,您可以构建一个包含所有必需依赖项,类和资源的可执行JAR文件,并运行该文件。这使得在整个开发生命周期中,跨不同环境等将服务作为应用程序发布,版本和部署变得容易。
如果您使用的是Gradle,则可以使用./gradlew bootRun。或者您可以使用构建JAR文件./gradlew build。然后你可以运行JAR文件:
java -jar build / libs / gs-access-data-neo4j-0.1.0.jar
如果您使用的是Maven,则可以使用该应用程序运行该应用程序./mvnw spring-boot:run。或者您可以使用构建JAR文件./mvnw clean package。然后你可以运行JAR文件:
java -jar target / gs-access-data-neo4j-0.1.0.jar
上面的过程将创建一个可运行的JAR。您也可以选择构建经典WAR文件。
你应该看到这样的东西(还有查询等其他东西):
Before linking up with Neo4j...
Greg's teammates => []
Roy's teammates => []
Craig's teammates => []
Lookup each person by name...
Greg's teammates => [Roy, Craig]
Roy's teammates => [Greg, Craig]
Craig's teammates => [Roy, Greg]
您可以从输出中看到,最初没有人通过任何关系连接。然后在添加人员后,他们被捆绑在一起。最后,您可以看到基于队友查找人员的方便查询。
摘要
恭喜!您只需设置一个嵌入式Neo4j服务器,存储一些简单的相关实体,并开发一些快速查询。
如果您对使用基于超媒体的RESTful前端轻松公开Neo4j存储库感兴趣,您可能希望阅读使用REST访问Neo4j数据。
扩展知识
Neo4j
Neo4j是一个高性能的,NOSQL图形数据库,它将结构化数据存储在网络上而不是表中。它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎,但是它将结构化数据存储在网络(从数学角度叫做图)上而不是表中。Neo4j也可以被看作是一个高性能的图引擎,该引擎具有成熟数据库的所有特性。程序员工作在一个面向对象的、灵活的网络结构下而不是严格、静态的表中——但是他们可以享受到具备完全的事务特性、企业级的数据库的所有好处。
修改Neo4j密码
使用浏览器访问 http://serverip:7474/,
进去以后随便点个命令会跳到http://serverip:7474/browser/地址,
会提示您登陆,
用neo4j:neo4j账号登陆后,
第一个界面就是让你修改密码,
然后重新设置一个密码即可。