原标题:Spring认证中国教育管理中心-Spring Data Neo4j教程一(Spring中国教育管理中心)
5. 开始
我们为 SDN 提供了 Spring Boot 启动器。请通过您的依赖管理包含启动模块并配置要使用的螺栓 URL,例如org.neo4j.driver.uri=bolt://localhost:7687. 启动器假定服务器已禁用身份验证。由于 SDN 启动器依赖于 Java 驱动程序的启动器,因此有关配置的所有内容在此处也适用。有关可用属性的参考,请使用org.neo4j.driver命名空间中的 IDE 自动完成功能或查看专用手册。
SDN支持
- 众所周知和理解的命令式编程模型(很像 Spring Data JDBC 或 JPA)
- 基于Reactive Streams的反应式编程,包括对反应式事务的完全支持。
这些都包含在同一个二进制文件中。反应式编程模型在数据库端需要 4.0 Neo4j 服务器,另一方面需要反应式 Spring。
5.1准备数据库对于这个例子,我们停留在movie graph 中,因为它随每个 Neo4j 实例免费提供。
如果您没有正在运行的数据库但安装了 Docker,请运行:
清单 1. 在 Docker 中启动一个本地 Neo4j 实例。
docker run --publish=7474:7474 --publish=7687:7687 -e 'NEO4J_AUTH=neo4j/secret' neo4j:4.3.6
您现在可以访问localhost:7474。上面的命令将服务器的密码设置为secret. :play movies请注意在提示符 ( )中准备好运行的命令。执行它以用一些测试数据填充您的数据库。
5.2.创建一个新的 Spring Boot 项目设置 Spring Boot 项目的最简单方法是start.spring.io (它也集成在主要 IDE 中,以防您不想使用该网站)。
选择“Spring Web Starter”以获取创建基于 Spring 的 Web 应用程序所需的所有依赖项。Spring Initializr 将负责为您创建一个有效的项目结构,其中包含所选构建工具的所有文件和设置。
5.2.1使用 Maven您可以针对 Spring Initializer 发出curl请求以创建基本的 Maven 项目:
清单 2. 使用 Spring Initializr 创建一个基本的 Maven 项目
curl start.spring.io/starter.tgz \
-d dependencies=webflux,actuator,data-neo4j \
-d bootVersion=2.5.3 \
-d baseDir=Neo4jSpringBootExample \
-d name=Neo4j SpringBoot Example | tar -xzvf -
这将创建一个新文件夹Neo4jSpringBootExample。由于这个启动器还没有在初始化器上,您必须手动将以下依赖项添加到您的pom.xml:
清单 3. 在 Maven 项目中包含 spring-data-neo4j-spring-boot-starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
如果是现有项目,您还可以手动添加依赖项。
5.2.2.使用 Gradle思路是一样的,只是生成一个Gradle项目:
清单 4. 使用 Spring Initializr 创建一个基本的 Gradle 项目
curl start.spring.io/starter.tgz \
-d dependencies=webflux,actuator,data-neo4j \
-d type=gradle-project \
-d bootVersion=2.5.3 \
-d baseDir=Neo4jSpringBootExampleGradle \
-d name=Neo4j SpringBoot Example | tar -xzvf -
Gradle 的依赖项如下所示,必须添加到build.gradle:
清单 5. 在 Gradle 项目中包含 spring-data-neo4j-spring-boot-starter
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-neo4j'
}
如果是现有项目,您还可以手动添加依赖项。
5.3.配置项目现在在您最喜欢的 IDE 中打开这些项目中的任何一个。查找application.properties并配置您的 Neo4j 凭据:
spring.neo4j.uri=bolt://localhost:7687
spring.neo4j.authentication.username=neo4j
spring.neo4j.authentication.password=secret
这是连接到 Neo4j 实例所需的最低限度。
使用此启动器时,无需添加驱动程序的任何编程配置。此启动器将自动启用 SDN 存储库。
5.4.在模块路径上运行 (Java 9 )Spring Data Neo4j 可以在模块路径上运行。它的自动模块名称是spring.data.neo4j. 由于当前 Spring Data 构建设置的限制,它本身不提供模块。因此,它使用自动但稳定的模块名称。但是,它确实依赖于模块化库(Cypher-DSL)。由于module-info.java上述限制,我们无法代表您表达对该库的要求。
因此,module-info.java您的项目中在模块路径上运行 Spring Data Neo4j 6.1 所需的最低要求如下:
清单 6.module-info.java项目中的 A 应该在模块路径上使用 Spring Data Neo4j
module your.module {
requires org.neo4j.cypherdsl.core;
requires spring.datamons;
requires spring.data.neo4j;
opens your.domain to spring.core;
exports your.domain;
}
Spring Data Neo4j 使用 Spring Data Commons 及其反射功能,因此您spring.core至少需要打开域包。
我们假设这里your.domain还包含存储库:必须导出这些存储库才能被
spring.beans,spring.context和访问spring.datamons。如果您不想将它们导出到世界,您可以将它们限制在这些模块中。
5.5.创建您的域我们的领域层应该完成两件事:
- 将图表映射到对象
- 提供访问这些
SDN 完全支持 Java 和dataKotlin 中的类的不可修改实体。因此,我们将在这里关注不可变实体,清单 7显示了这样一个实体。
SDN 支持 Neo4j Java 驱动程序支持的所有数据类型,请参阅“Cypher 类型系统”一章中将Neo4j 类型映射到本地语言类型。未来的版本将支持额外的转换器。
清单 7. MovieEntity.java
import java.util.ArrayList;
import java.utilst;
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.Relationship.Direction;
@Node("Movie")
public class MovieEntity {
@Id
private final String title;
@Property("tagline")
private final String description;
@Relationship(type = "ACTED_IN", direction = Direction.INCOMING)
private List<Roles> actorsAndRoles;
@Relationship(type = "DIRECTED", direction = Direction.INCOMING)
private List<PersonEntity> directors = new ArrayList<>();
public MovieEntity(String title, String description) {
this.title = title;
this.description = description;
}
// Getters omitted for brevity
}
@Node用于将此类标记为托管实体。它还用于配置 Neo4j 标签。如果您只是使用 plain ,标签默认为类的名称@Node。
每个实体都必须有一个 id。此处显示的电影类使用该属性title作为唯一的业务键。如果您没有这样的唯一密钥,您可以使用 和 的组合@Id来@GeneratedValue
配置 SDN 以使用 Neo4j 的内部 id。我们还提供 UUID 的生成器。
这显示@Property了为字段使用与图形属性不同的名称的一种方式。
这定义了一个关系到一个类的类型PersonEntity和关系类型ACTED_IN
这是您的应用程序代码要使用的构造函数。
作为一般评论:使用内部生成的 id 的不可变实体有点矛盾,因为 SDN 需要一种方法来使用数据库生成的值设置字段。
如果您找不到好的业务密钥或不想使用生成器生成 ID,这里是使用内部生成的 id 以及常规构造函数和所谓的wither -Method 的同一实体,SDN 使用该方法:
清单 8. MovieEntity.java
import org.springframework.data.neo4j.core.schema.GeneratedValue;
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.annotation.PersistenceConstructor;
@Node("Movie")
public class MovieEntity {
@Id @GeneratedValue
private Long id;
private final String title;
@Property("tagline")
private final String description;
public MovieEntity(String title, String description) {
this.id = null;
this.title = title;
this.description = description;
}
public MovieEntity withId(Long id) {
if (this.id.equals(id)) {
return this;
} else {
MovieEntity newObject = new MovieEntity(this.title, this.description);
newObject.id = id;
return newObject;
}
}
}
这是您的应用程序代码要使用的构造函数。它将 id 设置为 null,因为不应操纵包含内部 id 的字段。
这就是所谓的-属性凋零id。它创建一个新实体并相应地设置字段,而不修改原始实体,从而使其不可变。
您当然可以将 SDN 与Kotlin一起使用,并使用 Kotlin 的数据类对您的域进行建模。 如果您想或需要纯粹地留在 Java 中,Project Lombok是一个替代方案。
5.5.2.声明 Spring Data 存储库您在这里基本上有两个选择:您可以使用 SDN 以与商店无关的方式工作,并使您的域特定扩展之一
- org.springframework.data.repository.Repository
- org.springframework.data.repository.CrudRepository
- org.springframework.data.repository.reactive.ReactiveCrudRepository
- org.springframework.data.repository.reactive.ReactiveSortingRepository
相应地选择命令式和反应式。
虽然技术上不禁止,但不建议在同一个应用程序中混合命令式和反应式数据库访问。我们不会在这种情况下为您提供支持。
另一种选择是选择特定于商店的实现并获得我们开箱即用的所有方法。这种方法的优点也是它最大的缺点:一旦出来,所有这些方法都将成为您 API 的一部分。大多数时候,拿走东西比事后添加东西更难。此外,使用商店细节会将您的商店泄漏到您的域中。从性能的角度来看,没有惩罚。
适合上述任何电影实体的反应式存储库如下所示:
清单 9. MovieRepository.java
import reactor.core.publisher.Mono;
import org.springframework.data.neo4j.repository.ReactiveNeo4jRepository;
public interface MovieRepository extends ReactiveNeo4jRepository<MovieEntity, String> {
Mono<MovieEntity> findOneByTitle(String title);
}
测试响应式代码是使用reactor.test.StepVerifier. 查看Project Reactor的相应文档或查看我们的示例代码。
,