Neo4j图数据库学习(二)——SpringBoot整合Neo4j
一. 前言
本文介绍如何通过SpringBoot整合Neo4j的方式,对图数据库进行简单的操作。
Neo4j和SpringBoot的知识不再赘述。关于Neo4j的基础知识,有兴趣可以看看作者上一篇的文章:Neo4j图数据库学习(一)——初识CQL
二. 前置准备
新建SpringBoot项目
首先,新建一个SpringBoot项目,注意JDK与Java版本,需要与你的Neo4j版本相匹配。
接着添加依赖项,这里添加了Lombok与SpringDataNeo4j,Lombok可以使用@Data
注解为实体类快速生成get()、set()等方法。
我选择使用的SpringBoot版本在2.4以下,如果版本较高,集成的Neo4j的API规则方法变化较大。
properties配置文件
在properties中配置Neo4j的连接信息:
#Neo4j配置
spring.data.neo4j.uri= bolt://localhost:7687
spring.data.neo4j.username= neo4j
spring.data.neo4j.password= 123456
假如有修改过密码,记得将初始密码替换为自己设置的密码。
至此,前置的准备已经基本完毕。
三. 查询
我们知道,启动Neo4j后,可以在浏览器中对数据库进行操作,那么在SpringBoot中我们如何进行操作呢?
我们接着以小猪佩奇的案例进行分析。
我们需要有小猪佩奇的实体类,所以创建一个Pig
类,代码如下:
使用@NodeEntity
注解定义节点模型。
package com.tuling.lowversionneo4j.entity;
import lombok.Data;
import org.neo4j.ogm.annotation.GeneratedValue;
import org.neo4j.ogm.annotation.Id;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Property;
import java.io.Serializable;
@Data
@NodeEntity(label = "pig")
public class Pig implements Serializable {
@Id
@GeneratedValue
private Long id;
@Property
private String name;
}
使用spring-data-neo4j提供的Neo4jRepository
接口来创建数据访问层,可以使用@Repository
注解。
package com.tuling.lowversionneo4j.dao;
import com.tuling.lowversionneo4j.entity.Pig;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface PigReponsitory extends Neo4jRepository<Pig,Long> {
}
此时,如果我们要查询<id>
为2的成员信息,我们可以使用@Autowired
进行依赖注入,接着使用pigReponsitory
调用相关方法进行操作。
这里使用测试类进行简单演示,后续代码同样:
package com.tuling.lowversionneo4j;
import com.tuling.lowversionneo4j.dao.PigReponsitory;
import com.tuling.lowversionneo4j.entity.Pig;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Optional;
@SpringBootTest
class LowVersionNeo4jApplicationTests {
@Autowired
PigReponsitory pigReponsitory;
@Test
void test() {
Optional<Pig> byId = pigReponsitory.findById(2L); //注意此处传入的数据类型为Long
Pig pig = byId.get();
System.out.println(pig);
}
}
运行测试,在控制台中得到输出结果。可以看出,<id>
为2的家庭成员为佩奇。
四. 删除
同样地,我们也可以使用pigReponsitory
调用方法进行其他操作。如使用deleteById()
方法根据Id
进行删除。
我们以删除<id>
为5的节点为例,代码如下:
pigReponsitory.deleteById(5L); //注意此处传入的数据类型为Long
运行测试类,回到浏览器页面,可以发现<id>
为5的节点(猪爷爷)已被删除。
删除后:
pigReponsitory
可以调用其他方法来进行其他操作,在这里不多赘述,有兴趣可以自己研究。
五. 添加
添加节点
如果我们想要添加节点,该如何操作?
同样地,我们可以通过pigReponsitory
调用方法来实现。
如下方代码所示,我们创建两个pig对象并设置name
属性,最后通过调用save()
方法来添加节点。
Pig pig1 = new Pig();
pig1.setName("猪爷爷");
Pig pig2 = new Pig();
pig2.setName("猪奶奶");
pigReponsitory.save(pig1);
pigReponsitory.save(pig2);
添加关系
新建PigRelationShip和PigRelationShipRepository的方法
这是一种较为复杂的方法。
与创建PigReponsitory
、Pig
同理,我们在entity中创建PigRelationShip
:
package com.tuling.lowversionneo4j.dao;
import com.tuling.lowversionneo4j.entity.PigRelationShip;
import org.springframework.data.neo4j.repository.Neo4jRepository;
public interface PigRelationShipRepository extends Neo4jRepository<PigRelationShip,Long> {
}
在dao中创建PigRelationShipRepository
:
使用@StartNode
和@EndNode
注解,设置起始节点和结束节点。
package com.tuling.lowversionneo4j.entity;
import lombok.Data;
import org.neo4j.ogm.annotation.*;
import java.io.Serializable;
@Data
@RelationshipEntity(type ="夫妻")
public class PigRelationShip implements Serializable {
@Id
@GeneratedValue
private Long id;
@StartNode
private Pig start;
@EndNode
private Pig end;
@Property
private String relation;
}
在测试类中进行测试:
PigRelationShip ship = new PigRelationShip();
ship.setStart(pig1);
ship.setEnd(pig2);
ship.setRelation("夫妻");
pigRelationShipRepository.save(ship);
最终成功创建关系
使用@Query
注解
刚才提到的方法是较为繁琐的,spring-data-neo4j为我们提供了快捷的注解——@Query
在PigReponsitory
中,我们使用@Query
注解简化添加关系操作,在@Query()
中编写CQL语句,与MyBatis有些相似。
//上方内容省略
@Repository
public interface PigReponsitory extends Neo4jRepository<Pig,Long> {
@Query("match(n:pig{name:$from}) match(m:pig{name:$to}) create (n) -[:小猪佩奇家庭关系{relation:$relation}] -> (m)")
void createRelation(@Param(value="from")String from, @Param(value="relation")String relation, @Param(value="to")String to);
}
测试类中的代码:
pigReponsitory.createRelation("猪爷爷","夫妻", "猪奶奶");
在这里,作者也有一个问题,就是只有使用$name
和@Param
才能正常替换字符串内容,否则会报语法错误:
而似乎有人使用{}与参数序号的方式,可以成功实现。
@Repository
public interface PigReponsitory extends Neo4jRepository<Pig,Long> {
@Query("match(n:pig{name:{0}}) match(m:pig{name:{2}}) create (n) -[:小猪佩奇家庭关系{relation:{1}}] -> (m)")
void createRelation(String from, String relation, String to);
}
作者无法使用这种方法实现,不知为何,有知道的可以指导指导,作者感激不尽!
六. 最后
由于作者的水平非常有限,难免会出现错误,欢迎各位指正!假如您有任何想法,也欢迎交流!