springboot整合neo4j-使用原生cypher

这篇具有很好参考价值的文章主要介绍了springboot整合neo4j-使用原生cypher。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

该文的实现有更简单的方式,详见我的另一篇博客springboot整合neo4j–采用Neo4jClient和Neo4jTemplate方式

1.背景

Neo4j 提供 JAVA API 以编程方式执行所有数据库操作。它支持三种类型的API:
1、Neo4j 原生的 Java API
原生 Java API 是一种低级别的纯 JAVA API,用于执行数据库操作。
2、Neo4j Cypher Java API
Cypher Java API 是简单而强大的 JAVA API,用于执行所有CQL命令以执行数据库操作。
3、Neo4j OGM JAVA API
OGM Java API和Mybatis、JPA类似可以直接和SpringData整合

2.分析

目前很多项目针对neo4j的操作采用Neo4j OGM JAVA API,该方案与springboot整合之后可以使用@Query注解很方便的编写查询接口,比如这篇SpringBoot集成neo4j实战。
但是这种方式对图数据库的增删改查均依赖业务数据对象(就是你的Java bean对象,比如People、Company),如果我们数据类型很多且不断变化,那这种方式就不再适合。
Neo4j Cypher Java API对neo4j的操作是业务数据对象无关的,不管是什么样的节点数据或关系数据均可以操作。因为它是直接使用session执行cyhper语句。具体区别可自行查看下方代码。

3.代码实战

1.依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>chaos</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.0</version>
        <relativePath/>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.30</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-neo4j</artifactId>
            <!--<exclusions>
                <exclusion>
                    <artifactId>neo4j-java-driver</artifactId>
                    <groupId>org.neo4j.driver</groupId>
                </exclusion>
            </exclusions>-->
        </dependency>
      <!--  <dependency>
            <groupId>org.neo4j.driver</groupId>
            <artifactId>neo4j-java-driver</artifactId>
            <version>4.2.0</version>
        </dependency>-->
        
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
        <resources>
            <resource>
                <filtering>true</filtering>
                <directory>src/main/resources</directory>
                <excludes>
                    <!--<exclude>**/*</exclude>-->
                </excludes>
            </resource>
        </resources>

    </build>



</project>

1.Neo4jClientConfig

package com.dbs.neo4j.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Data
@Configuration
@ConfigurationProperties(prefix = "com.dbs.neo4j")
public class Neo4jClientConfig {
    private String uri;
    private String username;
    private String password;
}

**2.Neo4jClientService **

package com.win.chaos.service;

import com.win.chaos.config.Neo4jConfig;
import com.win.chaos.exception.Neo4jException;
import lombok.extern.slf4j.Slf4j;
import org.neo4j.driver.*;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class Neo4jClientService {

    private final Driver driver;

    public Neo4jClientService(Neo4jConfig neo4jConfig) {
        this.driver = GraphDatabase.driver(neo4jConfig.getUri(), AuthTokens.basic(neo4jConfig.getUsername(), neo4jConfig.getPassword()));
    }

    /**
     * 适用执行写逻辑
     * @param cypher cypher
     * @return Result 由于return之前session已经被关闭,该result不能被消费
     * @throws Neo4jException 执行cypher出现异常
     */
    public Result run(String cypher) throws Neo4jException {
        Session session = driver.session();
        Transaction ts = session.beginTransaction();
        try {
            Result result = ts.run(cypher);
            ts.commit();
            return result;
        } catch (Exception e) {
            ts.rollback();
            log.error("run neo4j cypher error with ", e);
            throw new Neo4jException("run " + cypher + " error with" + e.getMessage());
        }finally {
            ts.close();
            session.close();
        }
    }

    /**
     * 用于执行读或写cypher语句
     * @param gql cypher
     * @return Result
     * @throws Neo4jException 执行cypher出现异常
     */
    public Result exec(String gql) throws Neo4jException {
        try {
            Session session = driver.session();
            log.info("exec {}", gql);
            return session.run(gql);
        } catch (Exception e) {
            log.error("execute gql {} error ", gql, e);
            throw new Neo4jException("execute " + gql + " error with" + e.getMessage());
        }
    }
}

3.Controller

	@Resource 
	private Neo4jClientService  neo4jClient;

	//查询节点
    @GetMapping("/getNode")
    public Neo4jGraph getNode() throws Neo4jException {
        String ql = "MATCH (n:`公司`) RETURN n LIMIT 25";
        Result result = neo4jClient.run(ql);
        return Neo4jGraph.parse(result);
    }
    //查询路径
    @GetMapping("/matchPath")
    public Neo4jGraph matchPath() throws Neo4jException {
        String ql = "MATCH p=()-[r:`持股`]->() RETURN p LIMIT 25";
        Result result = neo4jClient.run(ql);
        return Neo4jGraph.parse(result);
    }
    //测试创建和删除
    @GetMapping("/test")
    public void add() throws Neo4jException {
        String addQL = "CREATE (o:people {name:\"里斯\",id:32435})";
        Result addResult = neo4jClient.run(addQL);

        String delQL = "match (n:people) delete n";
        Result delResult = neo4jClient.run(delQL);
    }

以上代码实现了springboot整合neo4j原生cypher,可以进行业务数据对象无关的操作。
代码中的Neo4jGraph.parse为解析查询对象接口。如有需要请看下面代码。
4.Neo4jGraph

package com.win.chaos.model.neo4j;

import cn.hutool.core.collection.ConcurrentHashSet;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.neo4j.driver.Record;
import org.neo4j.driver.Result;
import org.neo4j.driver.Value;
import org.neo4j.driver.internal.types.TypeConstructor;
import org.neo4j.driver.types.Node;
import org.neo4j.driver.types.Path;
import org.neo4j.driver.types.Relationship;
import org.neo4j.driver.types.Type;
import java.util.List;
import java.util.Set;

@Data
@Slf4j
public class Neo4jGraph {
    private Set<Neo4jNode> nodes = new ConcurrentHashSet<>();
    private Set<Neo4jEdge> edges = new ConcurrentHashSet<>();

    /**
     * 解析查询结果,目前仅解析节点(Node)、关系(Relationship)、路径(Path)三种查询结果类型
     * @param result 查询结果集
     * @return Neo4jGraph
     */
    public static Neo4jGraph parse(Result result) {
        if (result == null) return null;
        Neo4jGraph graph = new Neo4jGraph();
        List<Record> records = result.list();
        for (Record record:records){
            List<Value> values = record.values();
            for (Value value : values) {
                Type type = value.type();
                if (type.name().equals(TypeConstructor.NODE.name())) {
                    Node node = value.asNode();
                    graph.addNeo4jNode(new Neo4jNode(node));
                }else if (type.name().equals(TypeConstructor.PATH.name())) {
                    Path path = value.asPath();
                    path.nodes().forEach(node -> graph.addNeo4jNode(new Neo4jNode(node)));
                    path.relationships().forEach(relationship -> graph.addNeo4jEdge(new Neo4jEdge(relationship)));
                }else if (type.name().equals(TypeConstructor.RELATIONSHIP.name())) {
                    Relationship relationship = value.asRelationship();
                    graph.addNeo4jEdge(new Neo4jEdge(relationship));
                }else {
                    log.error("目前不支持{}类型的查询数据解析。", type.name());
                }
            }
        }
        return graph;
    }

    public void addNeo4jNode(Neo4jNode neo4jNode) {
        nodes.add(neo4jNode);
    }

    public void addNeo4jEdge(Neo4jEdge neo4jEdge) {
        edges.add(neo4jEdge);
    }

}

5.Neo4jNode

package com.win.chaos.model.neo4j;

import lombok.Data;
import org.neo4j.driver.types.Node;

import java.util.*;

@Data
public class Neo4jNode {

    private Object id;

    private List<String> labels = new ArrayList<>();

    private Map<String, Object> props = new HashMap<>();

    public Neo4jNode(Node node) {
        id = node.id();
        parseLabels(node);
        parseProp(node);
    }


    public void parseLabels(Node node){
        if (node.labels() != null){
            node.labels().forEach(labels::add);
        }
    }

    public void parseProp(Node node) {
        Map<String, Object> propsMap = node.asMap();
        Set<String> keys = propsMap.keySet();
        for (String key : keys){
            props.put(key, propsMap.get(key));
        }
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Neo4jNode vertex = (Neo4jNode) o;
        return id.equals(vertex.id);
    }

    @Override
    public int hashCode() {
        return id.hashCode();
    }
}

6.Neo4jEdge

package com.win.chaos.model.neo4j;

import lombok.Data;
import org.neo4j.driver.types.Relationship;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Data
public class Neo4jEdge {

    private long edgeId;

    private Object srcId;

    private Object dstId;

    private String label;

    private Map<String, Object> props = new HashMap<>();

    public Neo4jEdge(Relationship relationship) {
        srcId = relationship.startNodeId();
        dstId = relationship.endNodeId();
        edgeId = relationship.id();
        label = relationship.type();
        parseProps(relationship);
    }

    private void parseProps(Relationship relationship) {
        Map<String, Object> data = relationship.asMap();
        Set<String> keys = data.keySet();
        for (String key : keys) {
            props.put(key, data.get(key));
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Neo4jEdge that = (Neo4jEdge) o;
        //if (!edgeId.equals(that.edgeId)) return false;
        if (!srcId.equals(that.srcId)) return false;
        if (!dstId.equals(that.dstId)) return false;
        return label.equals(that.label);
    }

    @Override
    public int hashCode() {
        int result = srcId.hashCode();
        result = 31 * result + dstId.hashCode();
        result = 31 * result + label.hashCode();
        result = 31 * result + (int) (edgeId ^ (edgeId >>> 32));
        return result;
    }
}


完整代码:springboot_neo4j_hanlp

参考

图数据库 Neo4j Java Api 的使用文章来源地址https://www.toymoban.com/news/detail-660565.html

到了这里,关于springboot整合neo4j-使用原生cypher的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 图数据库_Neo4j和SpringBoot Data整合使用_实战创建明星关系图谱---Neo4j图数据库工作笔记0010

    2023-09-10 10:37:48 补充 注意:下面是旧版本的语法,如果你发现@NodeEntity这样的注解没有的话可以这样: 这里就要用@Node 另外如果@StartNode和@EndNode都没有了,那么说明是用法变了. 关于最新的用法,在官网有明确的说明和案例,很有用: 下面给出官网的案例:

    2024年02月09日
    浏览(38)
  • springboot整合neo4j模糊查询

    1.场景 查询与content相似的实体 解决方案: 1.直接从neo4j中查询所有实体并使用杰卡德相似度算法计算相似度,返回top n,该方案由于要匹配图中所有实体,性能较差。 2.模糊查询neo4j中的实体,并对查询结果与content做相似度计算,相似度算法为hutool中的TextSimilarity.similar()接口

    2024年02月13日
    浏览(28)
  • 图数据库_Neo4j和SpringBoot整合使用_创建节点_删除节点_创建关系_使用CQL操作图谱---Neo4j图数据库工作笔记0009

    首先需要引入依赖   springboot提供了一个spring data neo4j来操作 neo4j   可以看到它的架构   这个是下载下来的jar包来看看 有很多cypher对吧   可以看到就是通过封装的驱动来操作graph database   然后开始弄一下 首先添加依赖

    2024年02月12日
    浏览(38)
  • Springboot整合Neo4J图数据库

    1.引入依赖 JDK11, neo4J4.4.23 2.解决springboot与neo4j兼容问题

    2024年02月09日
    浏览(33)
  • SpringBoot 整合 Neo4j、MySQL 多数据源方案(Druid Mybatis DynamicDatasource)

    本文总结了Neo4j和Spring/SpringBoot、Alibaba Druid、Dynamic Datasource、Mybatis等整合方案,对相应配置做了详细说明。 添加Neo4j JDBC Driver依赖 添加application.yml配置 添加Neo4j JDBC Driver + Alibaba Druid依赖 添加application.yml配置 添加Neo4j JDBC Driver、Alibaba Druid、Dynamic DataSource依赖 添加application.y

    2023年04月08日
    浏览(41)
  • 图数据库Neo4j——SpringBoot使用Neo4j & 简单增删改查 & 复杂查询初步

    图形数据库是专门用于存储图形数据的数据库,它使用图形模型来存储数据,并且支持复杂的图形查询。常见的图形数据库有Neo4j、OrientDB等。 Neo4j是用Java实现的开源NoSQL图数据库,本篇博客介绍如何在SpringBoot中使用Neo4j图数据库,如何进行简单的增删改查,以及如何进行复杂

    2024年02月06日
    浏览(41)
  • Spring Boot整合neo4j

    相关版本信息 1、配置文件 Pom文件中引入依赖 Spring生态中Spring-data部分不仅仅提供了Spring-data-jpa , 也提供了Spring-data-neo4j 支持spring和 neo4j的完美融合,pom.xml 文件中依赖 yml文件中配置连接属性 2、实体类(NodeEntity) @NodeEntity: 标明是一个节点实体@RelationshipEntity:标明是一个

    2024年02月10日
    浏览(28)
  • springboot+neo4j

    请通过依赖项管理包含启动器模块并配置要使用的 Bolt URL,例如 spring.neo4j.uri=bolt://localhost:7687 。启动器假设服务器已禁用身份验证。由于 SDN 启动器依赖于 Java 驱动程序的启动器,因此此处所说的有关配置的所有内容也适用于此处。有关可用属性的参考,请在 spring.neo4j 命名

    2024年01月20日
    浏览(38)
  • 【neo4j】neo4j的安装与使用

    https://www.oracle.com/java/technologies/downloads/ 按照步骤安装即可 配置环境变量 在系统变量中添加 path变量中添加 https://neo4j.com/deployment-center/ 下载后,在指定位置解压缩 与java相同,也需要设置环境变量。 终端输入neo4j.bat console 成功

    2024年02月03日
    浏览(45)
  • 【Springboot集成Neo4j完整版教程】

    🚀 Neo4j 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,CSDN-Java领域优质创作者🏆,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文|经验

    2024年02月10日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包