Configuration neo4j intégrée à SpringBoot

Descriptif environnemental

MacOS Apple M1 | Jdk17 | Maven 3.8.5 | SpringBoot 2.6.9 | Neo4j 5.10.0
Remarque : Le plus gros piège intégré à neo4j est la compatibilité des versions, alors assurez-vous de vérifier la compatibilité des versions entre neo4j et springboot avant de l'introduire, et deuxièmement , entre les versions de neo4j En termes de configuration et d'utilisation, il y a une grande différence. Cet article concerne uniquement une version spécifique, il est donc recommandé de se référer à la documentation officielle du site Web pour les dernières méthodes de configuration et d'utilisation.

configuration

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()));
  }
}

Les nœuds personnalisés implémentent des méthodes courantes

neo4j peut générer automatiquement un identifiant unique pour chaque nœud du graphique et prend également en charge l'identifiant personnalisé via @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;
  }
}

Comment créer une clé unique

La clé unique de nom ColumnVertex est utilisée ici pour vérifier s'il existe une clé unique au démarrage du service, et la créer si elle n'existe pas

@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();
    }
  }
}

Guess you like

Origin blog.csdn.net/qq_38685503/article/details/132426856