gpt4 book ai didi

java - 如何使用@StartNode 关系查询 Neo4jRepository?

转载 作者:行者123 更新时间:2023-11-29 04:07:16 25 4
gpt4 key购买 nike

我有以下节点:

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@NodeEntity
public class Person {

@Id
@GeneratedValue
private Long id;

private String firstName;

private String lastName;

private LocalDate birthday;

@Email
private String email;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@NodeEntity
public class Skill {

@Id
@GeneratedValue
private Long id;

private String name;

private String description;
}

还有这个RelationshipEntity:

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@RelationshipEntity("RATED")
public class SkillRating {

@Id
@GeneratedValue
private Long id;

@Min(0)
@Max(100)
private Integer score;

private LocalDate measurementDate;

@StartNode
private Person person;

@EndNode
private Skill skill;
}

我不想加载我不打算使用的关系,即我不想添加:

@Relationship(type = "RATED")
private Set<SkillRating> skillRatings;

到我的 Person 类定义,以防止每次加载 Person 时加载这些评级。我想在必要时使用 Repository 方法加载它们。这是我尝试使用我对 JPA 存储库的了解:

@Repository
public interface SkillRatingRepository extends Neo4jRepository<SkillRating, Long> {
List<SkillRating> findAllByPerson(Person person);
}

但是这个方法并没有像预期的那样工作,因为它没有为一个人找到任何评级。我做错了什么?

-- 编辑--

MATCH (p)-[r:RATED]->(skill) WHERE id(p)={personId} RETURN r

我相信这是一个用 Neo4j Cypher 查询语言编写的查询,可以解决我的问题。我如何使用当前的类设置在 Repository 方法中“翻译”它?

最佳答案

感谢您的提问。

如您所见,我们不支持基于对象的派生查找器方法。与 @RelationshipEntity还有一个额外的限制,即派生的查找器方法仅针对属性而不是结束或开始节点。

话虽如此,我已经接受了您的项目(域类)并为您创建了一个解决方案。所以,域类 Person , SkillSkillRating可以按原样使用。

请申报您的SkillRatingRepository像这样:

import java.util.List;

import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.Neo4jRepository;

public interface SkillRatingRepository extends Neo4jRepository<SkillRating, Long> {

@Query("MATCH (p)-[r:RATED]->(skill) WHERE id(p) = :#{#person.id} RETURN p, r, skill")
List<SkillRating> findAllByPerson(Person person);
}

@Query表示自定义查询。在该自定义查询中,您可以使用 Spring 表达式语言 (SpEL),如此处所述 https://spring.io/blog/2014/07/15/spel-support-in-spring-data-jpa-query-definitions .

因此,您将取消引用已通过的人并访问该 ID。与您已经编写的查询非常相似。请注意,您还必须返回开始和结束节点才能使映射工作。

如果您运行一个标准的 Spring Boot 项目,那么参数名称会在编译期间保留,不需要其他注释。如果您不保留它们,请添加 @Param("person")到参数。

我注意到您使用的是 LocalDate在你的域中。 Neo4j 3.4+ 和 Java(又名 Bolt)驱动程序原生支持这些。

在当前版本的 Spring Data Neo4j 和随 Spring Boot 2.1.8 分发的 Neo4j-OGM 中,可以激活它们,如下面的测试所示(向下滚动到带 Config 注释的 @TestConfiguration 类):

import static org.assertj.core.api.Assertions.*;

import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.neo4j.ogm.config.Configuration;
import org.neo4j.ogm.driver.ParameterConversionMode;
import org.neo4j.ogm.session.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;

@SpringBootTest
@RunWith(SpringRunner.class)
@TestConfiguration
public class SkillRatingRepositoryTest {

@Autowired
private SkillRatingRepository skillRatingRepository;

@Autowired
private Session session;

@Autowired
private PlatformTransactionManager transactionManager;

@Test
public void retrievalOfSkillsShouldWork() {
Skill s = Skill.builder().name("Java")
.description("The Number one programming language everyone loves and hates").build();

new TransactionTemplate(transactionManager).execute(t -> {
session.purgeDatabase();
return null;
});

Person ms = Person.builder()
.firstName("Michael")
.lastName("Simons")
.build();
Person gm = Person.builder()
.firstName("Gerrit")
.lastName("M")
.build();
SkillRating r1 = SkillRating
.builder().person(ms)
.skill(s).measurementDate(LocalDate.now()).score(23).build();
SkillRating r2 = SkillRating
.builder().person(gm)
.skill(s).measurementDate(LocalDate.now()).score(42).build();

skillRatingRepository.saveAll(Arrays.asList(r1, r2));

List<SkillRating> skillRatings =
skillRatingRepository.findAllByPerson(gm);
assertThat(skillRatings).hasSize(1);
}

@TestConfiguration
static class Config {

@Bean
public org.neo4j.ogm.config.Configuration configuration() {
Configuration.Builder builder = new org.neo4j.ogm.config.Configuration.Builder();
builder.uri("bolt://localhost:7687");
builder.credentials("neo4j", "secret");
builder.withCustomProperty(ParameterConversionMode.CONFIG_PARAMETER_CONVERSION_MODE,
ParameterConversionMode.CONVERT_NON_NATIVE_ONLY);
return builder.build();
}
}
}

请注意,我既没有使用嵌入式实例进行测试,也没有使用 @DataNeo4jTest .想要查看我本地运行的实例中创建的数据。

我还建议不要在测试中使用嵌入式数据库,而是测试容器,也就是您将在生产中运行的“真实事物”:https://medium.com/neo4j/testing-your-neo4j-based-java-application-34bef487cc3c

作为最终引用,这里是 POM我用了。如果这个东西有用并解决了您的问题,请接受答案。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>neo4j</groupId>
<artifactId>so_re</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>so_re</name>
<description>Demo project for Spring Boot</description>

<properties>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

关于java - 如何使用@StartNode 关系查询 Neo4jRepository?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57852233/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com