Neo4j是目前最为流行的图数据库,如何在Java中对其进行简单的节点操作呢?Spring Data Neo4j为我们提供了方便的接口对Neo4j进行简单的操作。
引入依赖
在Spring Boot中使用Spring Data Neo4j首先需要引入依赖,使用maven进行管理如下
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
接着配置neo4j数据库的连接,在其中指定数据库uri、用户名和密码
# neo4j配置
spring.neo4j.uri=bolt://localhost:7687
spring.neo4j.authentication.username=neo4j
spring.neo4j.authentication.password=123456
定义实体类
定义一个电影的实体类如下,首先通过@Node
注解声明这是图数据库中的一个节点,指定节点名称为“Movie”。
接着利用@Id
注解指定主键,@Property
指定名为“tagline”的属性.
通过@Relationship
指定类型为"ACTED_IN"、"DIRECTED"的关系,该关系默认指向List定义的Actor节点,也可以自己对关系进行定义。只要将一个Actor对象添加到actors的List中,就会自动创建指向本节点的关系。
@Node("Movie")
public class Movie {
@Id
private final String title;
@Property("tagline")
private final String description;
@Relationship(type = "ACTED_IN", direction = Direction.INCOMING)
private List<Actor> actors = new ArrayList<>(); //自定义Actor关系
@Relationship(type = "DIRECTED", direction = Direction.INCOMING)
private List<Person> directors = new ArrayList<>(); //默认指向Person节点的关系
private Integer released;
public Movie(String title, String description) {
this.title = title;
this.description = description;
}
}
@Node
public class Person {
@Id
private final String name;
private Integer born;
public Person(Integer born, String name) {
this.born = born;
this.name = name;
}
}
如下所示通过@RelationshipProperties
对关系Actor进行自定义,通过@TargetNode
指向目标节点
@RelationshipProperties
public class Actor {
@TargetNode
private final Person person;
private List<String> roles = new ArrayList<>();
public Actor(Person person) {
this.person = person;
}
}
定义接口
接着我们定义相关实体类的实现接口,通过继承Neo4jRepository
接口,<Movie, String>
将返回节点映射为Movie对象,并且主键映射为String类型。
Spring Data会自动实现接口的增删改查方法,例如findById()
根据主键进行查询,然后将返回结果映射为Movie。可以看到所有方法的返回结果都是Movie类型或是其列表,在定义了<Movie, String>
的Repository内不能返回其他类型的数据,否则会映射错误,例如我们查询Person类型的数据,SDN依旧会尝试映射为Movie类,出现数据匹配失败会报错。
也可以通过@Query
注解自定义数据库查询方法,在其中Cypher语句中通过{0}
传入参数
interface MovieRepository extends Neo4jRepository<Movie, String> {
List<Movie> findAll();
Optional<Movie> findById(String title);
Optional<Movie> findOneByTitle(String title);
List<Movie> findAllByTitleLikeIgnoreCase(String title);
List<Movie> findAllByDirectorsName(String name);
@Query("MATCH (m:Movie {title:{0}}) RETURN m")
List<Movie> findMovies(String title);
}
创建节点和关系
如下对节点进行简单的创建和操作,如果希望将Person节点指向Movie节点,只需要把Person节点添加到Movie的Directors数组中即可
public void addActor(String title, TrackNode newTrackNode){
Movie movie = movieRepository.findMovieByTitle(title); //通过接口获取节点
List<Person> directors = movie.getDirectors (); //获取movie的directors关系数组
Person person = new Person("2020", "Tory"); //创建人物节点
directors.add(person); //将person节点通过directors关系指向movie
movieRepository.save(movie); //保存movie节点
}