zoukankan      html  css  js  c++  java
  • Neo4j学习实录 下载-安装-springboot操作neo4j

    由于课程作业的原因,今天简单学习了一下Neo4j数据库。

    下载和安装很简单,去官网下载即可

    基本元素的介绍

    节点:表示一个实体记录,就像关系数据库当中一条记录。一个节点包含多个属性和标签

     

    关系:关系用于将节点关联起来构成图,关系也称为图论的边

     

    属性:节点和关系都可以有多个属性。属性由键值对组成,就像哈希

     

    标签:指示一组拥有相同属性的节点,但不强制要求相同,一个节点可以有多个标签

     

    路径:图中任意俩个节点都存在由关系组成的路径

     

    Neo4j的操作语句借鉴了sql,基本语法有点相似

    CQL代表Cypher查询语言。 像Oracle数据库具有查询语言SQL,Neo4j具有CQL作为查询语言。

    Neo4j CQL -

    • 它是Neo4j图形数据库的查询语言。

    • 它是一种声明性模式匹配语言

    • 它遵循SQL语法。

    • 它的语法是非常简单且人性化、可读的格式。

    增加节点-- create

    create (book:Book)

    删除节点 delete

    MATCH (n:`孙鹏翔`) delete n

    修改 set

    MATCH (book:Book) SET book.title = '红楼梦' RETURN book

     我们可以看到book节点的属性中有了title

     

    查询 match

    实际上所有的操作基本都是基于查询的,只有先查到才能进行增删改

     

     

    Neo4j的模板数据

     这三个分别是不同的模板数据,相当于一个官方教程,第一个是语句创建图形数据,第二个是读取csv文件创建,第三个是查询数据的模板

    可以通过这三个来深入理解Neo4j的使用

    小知识:Neo4j的前端展示是通过d3.js来实现的。

    注意:后面springboot整合Neo4j操作的数据就是第一个模板数据

    SpringBoot操作Neo4j

    第一步:引入依赖(使用maven)

    pom.xml

    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    </dependency>
    <dependency>
    <groupId>org.neo4j.driver</groupId>
    <artifactId>neo4j-java-driver</artifactId>
    <version>1.4.4</version>
    </dependency>
    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.0.9.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-test</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-test-autoconfigure</artifactId>
    </dependency>
    <!-- thymeleaf依赖 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    </dependencies>

     第二步 yml的配置

    server:
    port: 8888
    neo4j:
    url: bolt://127.0.0.1:7687
    username: neo4j
    password: 123456
    第三步 Neo4j驱动配置

    Neo4jConf.java 

    package com.mn.springboot.utils;

    import org.neo4j.driver.v1.AuthTokens;
    import org.neo4j.driver.v1.Driver;
    import org.neo4j.driver.v1.GraphDatabase;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;

    /**
    * neo4j配置
    */
    @Configuration
    public class Neo4jConf {
    @Value("${neo4j.url}")
    private String url;
    @Value("${neo4j.username}")
    private String username;
    @Value("${neo4j.password}")
    private String password;

    @Bean(name = "driver")
    public Driver initDriver() {
    Driver driver;
    try {
    driver = GraphDatabase.driver(url, AuthTokens.basic(username, password));
    } catch (Exception e) {
    throw new RuntimeException(e);
    }
    return driver;
    }
    }
    第四步 工具类

    实际上就相当于mapper/dao 层,与数据库进行交互,操作Neo4j数据库,对数据进行封装
    
    
    package com.mn.springboot.utils;

    import org.neo4j.driver.internal.InternalNode;
    import org.neo4j.driver.internal.InternalRelationship;
    import org.neo4j.driver.v1.*;
    import org.neo4j.driver.v1.types.Node;
    import org.neo4j.driver.v1.types.Path;
    import org.neo4j.driver.v1.types.Relationship;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;

    import java.util.*;

    /**
    * 通用的neo4j调用类
    *
    * @version 1.0 18-6-5 上午11:21
    */
    @Component
    public class Neo4jUtil {
    private static Driver driver;

    @Autowired
    public Neo4jUtil(Driver driver) {
    Neo4jUtil.driver = driver;
    }

    /**
    * cql的return返回多种节点match (n)-[edge]-(n) return n,m,edge:限定返回关系时,关系的别名必须“包含”edge
    * @param cql 查询语句
    * @param lists 和cql的return返回节点顺序对应
    * @return List<Map<String,Object>>
    */
    public static <T> void getList(String cql, Set<T>... lists) {
    //用于给每个Set list赋值
    int listIndex = 0;
    try {
    Session session = driver.session();
    StatementResult result = session.run(cql);
    List<Record> list = result.list();
    for (Record r : list) {
    if (r.size() != lists.length) {
    System.out.println("节点数和lists数不匹配");
    return;
    }
    }
    for (Record r : list) {
    for (String index : r.keys()) {
    //对于关系的封装
    if (index.indexOf("edge") != -1) {
    Map<String, Object> map = new HashMap<>();
    //关系上设置的属性
    map.putAll(r.get(index).asMap());
    //外加三个固定属性
    map.put("edgeId", r.get(index).asRelationship().id());
    map.put("edgeFrom", r.get(index).asRelationship().startNodeId());
    map.put("edgeTo", r.get(index).asRelationship().endNodeId());
    lists[listIndex++].add((T) map);
    }
    //对于节点的封装
    else {
    Map<String, Object> map = new HashMap<>();
    //关系上设置的属性
    map.putAll(r.get(index).asMap());
    //外加一个固定属性
    map.put("nodeId", r.get(index).asNode().id());
    lists[listIndex++].add((T) map);
    }
    }
    listIndex = 0;
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    }

    /**
    * cql 路径查询 返回节点和关系
    * @param cql 查询语句
    * @param nodeList 节点
    * @param edgeList 关系
    * @return List<Map<String,Object>>
    */
    public static <T> void getPathList(String cql, Set<T> nodeList, Set<T> edgeList) {
    try {
    Session session = driver.session();
    StatementResult result = session.run(cql);
    List<Record> list = result.list();
    for (Record r : list) {
    for (String index : r.keys()) {
    Path path = r.get(index).asPath();
    //节点
    Iterable<Node> nodes = path.nodes();
    for (Iterator iter = nodes.iterator(); iter.hasNext(); ) {
    InternalNode nodeInter = (InternalNode) iter.next();
    Map<String, Object> map = new HashMap<>();
    //节点上设置的属性
    map.putAll(nodeInter.asMap());
    //外加一个固定属性
    map.put("nodeId", nodeInter.id());
    nodeList.add((T) map);
    }
    //关系
    Iterable<Relationship> edges = path.relationships();
    for (Iterator iter = edges.iterator(); iter.hasNext(); ) {
    InternalRelationship relationInter = (InternalRelationship) iter.next();
    Map<String, Object> map = new HashMap<>();
    map.putAll(relationInter.asMap());
    //关系上设置的属性
    map.put("edgeId", relationInter.id());
    map.put("edgeFrom", relationInter.startNodeId());
    map.put("edgeTo", relationInter.endNodeId());
    edgeList.add((T) map);
    }
    }
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    }

    /**
    * cql 返回具体的属性, 如match (n)-[]-() return n.id,n.name,match (n)-[]-() return count(n)
    * @param cql 查询语句
    * @return List<Map<String,Object>>
    */
    public static List<Map<String, Object>> getFields(String cql) {
    List<Map<String, Object>> resList = new ArrayList<>();
    try {
    Session session = driver.session();
    StatementResult result = session.run(cql);
    List<Record> list = result.list();
    for (Record r : list) {
    resList.add(r.asMap());
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    return resList;
    }

    /**
    * 执行添加cql
    * @param cql 查询语句
    */
    public static void add(String cql) {
    //启动事务
    try (Session session = driver.session();
    Transaction tx = session.beginTransaction()) {
    tx.run(cql);
    //提交事务
    tx.success();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }
    第五步 controller开发
    package com.mn.springboot.controller;

    import com.mn.springboot.utils.Neo4jUtil;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;

    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.Map;
    import java.util.Set;

    @RestController
    public class TestController {
    @Autowired
    private Neo4jUtil neo4jUtil;

    @GetMapping("get")
    public Map<String, Object> get() {
    Map<String, Object> retMap = new HashMap<>();
    //cql语句
    String cql = "match (m:Person{name: "Meg Ryan"}) return m";
    Set<Map<String, Object>> nodeList = new HashSet<>();
    neo4jUtil.getList(cql, nodeList);
    retMap.put("nodeList", nodeList);
    return retMap;
    }
    controller层用于与前端交互,进行数据展示,这里只写了简单的get方法,进行一波测试,后面增删改查自由扩展
    get请求查询的结果,实际开发中我们要用postman或者swagger进行接口测试,这里我就偷懒了。
     
  • 相关阅读:
    🌏HTML文档结构与标签语法
    🌎HTML简介
    🍖Web前端介绍Web前端介绍
    🍖事务隔离机制
    🍖多版本并发控制 MVCC 的快照读与当前读简介
    🍖MySQL锁机制
    🍖数据库读现象(问题)
    hashlib 模块用来进行hash
    Logging 模块
    config parser 模块
  • 原文地址:https://www.cnblogs.com/spx88/p/14144888.html
Copyright © 2011-2022 走看看