SpringBoot内嵌neo4j配置

环境说明

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();
    }
  }
}
相关推荐
web行路人8 小时前
Spring Boot 第四周:集成 Spring Security 与 JWT 鉴权实践
spring boot·后端·spring
用户298698530148 小时前
Python 实现 Excel 到 ODS、XPS、PostScript 及 PDF/A-1b 的格式转换
后端·python·excel
爱勇宝8 小时前
AI 时代,更稀缺的是「提出好问题」还是「判断好答案」?
前端·人工智能·后端
逝水无殇8 小时前
C# 正则表达式详解
开发语言·后端·正则表达式·c#
老孙讲技术8 小时前
集成商选型笔记:原生 OpenSDK(低延迟)vs Web 轻应用(7 天上线)怎么选
后端
大鸡腿同学9 小时前
AI 智能剪辑
后端
运维行者_9 小时前
广域网性能监控:分布式IT架构下的链路质量保障
开发语言·网络·分布式·后端·架构·数据库架构
灯澜忆梦9 小时前
GO---map函数
开发语言·前端·后端·golang
QQ_21696290969 小时前
【项目编号:project05966】SpringBoot/Vue 电影推荐系统:用户端推荐、电影资讯与后台数据管理全流程
vue.js·spring boot·后端
吴声子夜歌9 小时前
Redis 6.x——整合SpringBoot
数据库·spring boot·redis