环境说明
MacOS Apple M1 | Jdk17 | Maven 3.8.5 | SpringBoot 2.6.9 | neo4j 5.10.0
注:neo4j 内嵌最大的坑就是版本兼容性,所以引入前一定检查 neo4j 与 springboot 版本兼容性,其次 neo4j 各版本间配置使用上,区别也挺大的,本文只针对特定版本,因此建议更多参考官网文档,有最新的配置使用方法。
配置
pom.xml
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j</artifactId>
<version>5.10.0</version>
</dependency>
Configuration
import org.neo4j.dbms.api.DatabaseManagementService;
import org.neo4j.dbms.api.DatabaseManagementServiceBuilder;
import org.neo4j.graphdb.GraphDatabaseService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.nio.file.Path;
import static org.neo4j.configuration.GraphDatabaseSettings.DEFAULT_DATABASE_NAME;
@Configuration
public class Neo4jConfig {
@Bean
public GraphDatabaseService graphDatabaseService() {
// graph.db 为自定义 neo4j 库目录位置
DatabaseManagementService managementService =
new DatabaseManagementServiceBuilder(Path.of("graph.db")).build();
GraphDatabaseService graphDb = managementService.database(DEFAULT_DATABASE_NAME);
registerShutdownHook(managementService);
return graphDb;
}
private static void registerShutdownHook(final DatabaseManagementService managementService) {
// Registers a shutdown hook for the Neo4j instance so that it
// shuts down nicely when the VM exits (even if you "Ctrl-C" the
// running application).
Runtime.getRuntime().addShutdownHook(new Thread(() -> managementService.shutdown()));
}
}
自定义节点 实现通用方法
neo4j 可以对每个图节点自动生成一个唯一 id,也支持通过 @Id 自定义 id
// Node
public class ColumnVertex {
private String name;
}
// Service
public interface EmbeddedGraphService {
// 添加图节点
void addColumnVertex(ColumnVertex currentVertex, ColumnVertex upstreamVertex);
// 寻找上游节点
List<ColumnVertex> findUpstreamColumnVertex(ColumnVertex currentVertex);
// 寻找下游节点
List<ColumnVertex> findDownstreamColumnVertex(ColumnVertex currentVertex);
}
// Impl
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Result;
import org.neo4j.graphdb.Transaction;
import org.springframework.stereotype.Service;
@Service
public class EmbeddedGraphServiceImpl implements EmbeddedGraphService {
@Resource private GraphDatabaseService graphDb;
@Override
public void addColumnVertex(ColumnVertex currentVertex, ColumnVertex upstreamVertex) {
try (Transaction tx = graphDb.beginTx()) {
tx.execute(
"MERGE (c:ColumnVertex {name: $currentName}) MERGE (u:ColumnVertex {name: $upstreamName})"
+ " MERGE (u)-[:UPSTREAM]->(c)",
Map.of("currentName", currentVertex.getName(), "upstreamName", upstreamVertex.getName()));
tx.commit();
}
}
@Override
public List<ColumnVertex> findUpstreamColumnVertex(ColumnVertex currentVertex) {
List<ColumnVertex> result = new ArrayList<>();
try (Transaction tx = graphDb.beginTx()) {
Result queryResult =
tx.execute(
"MATCH (u:ColumnVertex)-[:UPSTREAM]->(c:ColumnVertex) WHERE c.name = $name RETURN"
+ " u.name AS name",
Map.of("name", currentVertex.getName()));
while (queryResult.hasNext()) {
Map<String, Object> row = queryResult.next();
result.add(new ColumnVertex().setName((String) row.get("name")));
}
tx.commit();
}
return result;
}
@Override
public List<ColumnVertex> findDownstreamColumnVertex(ColumnVertex currentVertex) {
List<ColumnVertex> result = new ArrayList<>();
try (Transaction tx = graphDb.beginTx()) {
Result queryResult =
tx.execute(
"MATCH (c:ColumnVertex)-[:UPSTREAM]->(d:ColumnVertex) WHERE c.name = $name RETURN"
+ " d.name AS name",
Map.of("name", currentVertex.getName()));
while (queryResult.hasNext()) {
Map<String, Object> row = queryResult.next();
result.add(new ColumnVertex().setName((String) row.get("name")));
}
tx.commit();
}
return result;
}
}
如何创建唯一键
这里使用 name ColumnVertex 的唯一键,在启动服务时检查是否存在唯一键,不存在则创建
@Service
public class EmbeddedGraphServiceImpl implements EmbeddedGraphService {
@Resource private GraphDatabaseService graphDb;
@PostConstruct
public void init() {
try (Transaction tx = graphDb.beginTx()) {
Result result = tx.execute("SHOW CONSTRAINTS");
boolean constraintExists = false;
while (result.hasNext()) {
Map<String, Object> row = result.next();
if (((List<Object>) row.get("labelsOrTypes")).contains("ColumnVertex")
&& ((List<Object>) row.get("properties")).contains("name")
&& "UNIQUENESS".equals(row.get("type"))) {
constraintExists = true;
break;
}
}
if (!constraintExists) {
tx.execute("CREATE CONSTRAINT FOR (c:ColumnVertex) REQUIRE c.name IS UNIQUE");
}
tx.commit();
}
}
}
标签:内嵌,Springboot,tx,org,ColumnVertex,import,neo4j,name
From: https://www.cnblogs.com/pandacode/p/17644239.html