springboot整合neo4j-使用原生cypher Java API

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

该文的实现有更简单的方式,详见我的另一篇博客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-702472.html

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

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

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

相关文章

  • SpringBoot整合Neo4j

    Neo4j是一个高性能的,NOSQL图形数据库,它的内部就是一个高性能的图形引擎,专门为应用程序提供嵌入式,磁盘的高性能存储和遍历图形结构的能力。Spring Boot是一个旨在简化创建独立的,生产级别的Spring基础应用程序的开发框架。在本文中,我们将探讨如何在Spring Boot项目

    2024年02月06日
    浏览(49)
  • 图数据库_Neo4j和SpringBoot Data整合使用_实战创建明星关系图谱---Neo4j图数据库工作笔记0010

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

    2024年02月09日
    浏览(49)
  • Neo4j 与 Cypher 基础

    更好的阅读体验 huge{color{red}{更好的阅读体验}} 更好的阅读体验 Neo4j 是用 Java 实现的开源 NoSQL 图数据库。从2003年开始开发,2007年正式发布第一版,其源码托管于 GitHub。 与常见的关系型数据库不同, Neo4j 基于图图结构来表示和存储数据,并提供了申明式的查询语言 Cypher

    2024年02月07日
    浏览(46)
  • neo4j教程-Cypher操作

    Cypher是图形存储数据库Neo4j的查询语言,Cypher是通过模式匹配Neo4j数据库中的节点和关系,从而对数据库Neo4j中的节点和关系进行一系列的相关操作。 下面,通过一张表来介绍一下常用的Neo4j操作命令及相关说明,具体如表所示。 操作命令 相关说明 CREATE 创建节点、关系 MATC

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

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

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

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

    2024年02月12日
    浏览(48)
  • neo4j查询语言Cypher详解(三)--函数

    Cypher中的函数如果输入参数为null,则返回null。 以字符串作为输入的函数都对Unicode字符进行操作,而不是对标准字符进行操作。例如,size()函数应用于任何Unicode字符将返回1,即使该字符不适合一个字符的16位。 可以通过 SHOW FUNCTIONS 查看函数定义。 函数签名中参数格式:e

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

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

    2024年02月09日
    浏览(46)
  • 图数据库Neo4j——Neo4j简介、数据结构 & Docker版本的部署安装 & Cypher语句的入门

    MySQL是一种开源的关系型数据库管理系统,使用SQL作为其查询语言,常见的关系型数据库有MySQL、Oracle、SQL Server、PostgreSQL等。相关博客文章如下: 【合集】MySQL的入门进阶强化——从 普通人 到 超级赛亚人 的 华丽转身 PostgreSQL数据库——Docker版本的postgres安装 Navicat连接方式

    2024年02月06日
    浏览(63)
  • neo4j查询语言Cypher详解(一)--语法和子句

    neo4j 的图查询语言叫 Cypher 。Cypher的独特之处在于它提供了一种匹配模式和关系的可视化方式。 (nodes)-[:ARE_CONNECTED_TO]-(otherNodes) 使用圆角括号表示节点(nodes), -[:ARROWS]- 表示关系。 Cypher解析器接受任意输入字符串。 unicode 通常可以使用转义 uxxx 。 支持的空白符 描述 Unicode 字

    2024年02月14日
    浏览(55)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包