天天看點

SpringBoot使用Neo4j

1.Neo4j簡介

Neo4j是一個高性能的,NOSQL圖形資料庫,它将結構化資料存儲在網絡上而不是表中。它是一個嵌入式的、基于磁盤的、具備完全的事務特性的Java持久化引擎,但是它将結構化資料存儲在網絡(從數學角度叫做圖)上而不是表中。Neo4j也可以被看作是一個高性能的圖引擎,該引擎具有成熟資料庫的所有特性。程式員工作在一個面向對象的、靈活的網絡結構下而不是嚴格、靜态的表中——但是他們可以享受到具備完全的事務特性、企業級的資料庫的所有好處。

Neo4j的官方網站:

http://www.neo4j.org

2.安裝Neo4j

網上安裝教程很多,本文是在mac電腦下使用docker+Kitematic安裝的,步驟大緻如下:

1.啟動docker

2.在Kitematic中搜尋Neo4j鏡像并安裝,這裡安利一下這個軟體,安裝一些鏡像非常友善,如下圖:

3.安裝完成後,通路對應web位址,如下:

3.SpringBoot整合

接下來介紹SpringBoot中如何視同Neo4j。

3.1 添加Neo4j依賴

建立項目,pom檔案中引入依賴,如下:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>           

3.2 配置檔案

在配置檔案中配置Neo4j相關配置,如下:

# neo4j配置
spring.data.neo4j.uri= bolt://localhost:7687
spring.data.neo4j.username=neo4j
spring.data.neo4j.password=neo4j           

3.3 建立對應entity

這裡以部門為例,要建立一個如下的圖:

* CEO
     *    -設計部
     *        - 設計1組
     *        - 設計2組
     *    -技術部
     *        - 前端技術部
     *        - 後端技術部
     *        - 測試技術部           

那麼這裡簡單建立一個部門實體和一個關系實體。

其中部門實體,如下:

@NodeEntity(label = "dept")
@Data
@Builder
public class Dept {

    @Id
    @GeneratedValue
    private Long id;

    @Property(name = "deptName")
    private String deptName;

}           

關系實體如下:

@RelationshipEntity(type = "relationShip")
@Data
@Builder
public class RelationShip {

    @Id
    @GeneratedValue
    private Long id;

    @StartNode
    private Dept parent;

    @EndNode
    private Dept child;
}           

這裡說明一下幾個注解的意思:

  • @NodeEntity:标明是一個節點實體
  • @RelationshipEntity:标明是一個關系實體
  • @Id:實體主鍵
  • @Property:實體屬性
  • @GeneratedValue:實體屬性值自增
  • @StartNode:開始節點(可以了解為父節點)
  • @EndNode:結束節點(可以了解為子節點)

3.4 repository

由于使用的spring-data操作neo4j,是以實作邏輯類似,建立接口繼承Neo4jRepository。

DeptRepository如下:

import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface DeptRepository extends Neo4jRepository<Dept,Long> {

}           

RelationShipRepository如下:

import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface RelationShipRepository extends Neo4jRepository<RelationShip, Long> {

}
           

3.5 基本使用

這裡建立了一些基礎方法,使用方式和spring-data-jpa類似,由于需要建構一個本文3.1所描述的圖,是以建立了一個create方法來初始化資料,完整代碼如下:

@RestController
public class TestController {

    @Resource
    private DeptRepository deptRepository;
    @Resource
    private RelationShipRepository relationShipRepository;

    /**
     * CEO
     *    -設計部
     *        - 設計1組
     *        - 設計2組
     *    -技術部
     *        - 前端技術部
     *        - 後端技術部
     *        - 測試技術部
     */
    @GetMapping("create")
    public void create(){
        Dept CEO = Dept.builder().deptName("CEO").build();
        Dept dept1 = Dept.builder().deptName("設計部").build();
        Dept dept11 = Dept.builder().deptName("設計1組").build();
        Dept dept12 = Dept.builder().deptName("設計2組").build();

        Dept dept2 = Dept.builder().deptName("技術部").build();
        Dept dept21 = Dept.builder().deptName("前端技術部").build();
        Dept dept22 = Dept.builder().deptName("後端技術部").build();
        Dept dept23 = Dept.builder().deptName("測試技術部").build();
        List<Dept> depts = new ArrayList<>(Arrays.asList(CEO,dept1,dept11,dept12,dept2,dept21,dept22,dept23));
        deptRepository.saveAll(depts);

        RelationShip relationShip1 = RelationShip.builder().parent(CEO).child(dept1).build();
        RelationShip relationShip2 = RelationShip.builder().parent(CEO).child(dept2).build();
        RelationShip relationShip3 = RelationShip.builder().parent(dept1).child(dept11).build();
        RelationShip relationShip4 = RelationShip.builder().parent(dept1).child(dept12).build();
        RelationShip relationShip5 = RelationShip.builder().parent(dept2).child(dept21).build();
        RelationShip relationShip6 = RelationShip.builder().parent(dept2).child(dept22).build();
        RelationShip relationShip7 = RelationShip.builder().parent(dept2).child(dept23).build();
        List<RelationShip> relationShips = new ArrayList<>(Arrays.asList(relationShip1,relationShip2,relationShip3,relationShip4,relationShip5
                ,relationShip6,relationShip7));
        relationShipRepository.saveAll(relationShips);
    }

    @GetMapping("get")
    public RelationShip get(Long id){
        Optional<RelationShip> byId = relationShipRepository.findById(id);
        return byId.orElse(null);
    }

    @GetMapping("deleteRelationShip")
    public void deleteRelationShip(Long id){
        relationShipRepository.deleteById(id);
    }

    @GetMapping("deleteDept")
    public void deleteDept(Long id){
        deptRepository.deleteById(id);
    }

    @GetMapping("deleteAll")
    public void deleteAll(){
        deptRepository.deleteAll();
        relationShipRepository.deleteAll();
    }
}           

執行create方法初始化資料,結果如下圖所示:

其餘測試方法這裡就不在示範了,可以自行測試。

4.Neo4j基本指令

4.1 操作指令簡介

接下來介紹一下Neo4j的基本操作指令。

  • CREATE指令:建立節點指令
  • MATCH指令:查詢指令
  • RETURN指令:傳回資料指令
  • DELETE指令:删除指令,可以用于删除節點和關聯節點資訊
  • REMOVE指令:可以用于删除标簽和屬性

4.2 簡單練習

建立指令,可以用來建立節點和關系節點,比如我們要在建立一個部門,秘書部,如下,執行如下指令:

CREATE (d:dept {deptName:"秘書部"})           

操作後如下圖所示:

目前可以看到,秘書部和其餘節點是沒有關系的,那麼接下來将秘書部與CEO建立關系,執行如下指令:

MATCH (n:dept {deptName:"CEO"}),(m:dept {deptName:"秘書部"}) CREATE (n)-[r:relationShip]->(m) return r;           

檢視結果如圖:

可以看到秘書部已經挂在了CEO節點下。

其中從上面就可以看出,CQL語句大緻結構如下:

  • MATCH RETURN:查詢命中結果傳回;
  • MATCH CREATE RETURN:查詢後建立關系傳回;
  • MATCH DELETE:查詢命中删除;

...

5.源碼

源碼位址:

https://gitee.com/dalaoyang/springboot_learn/tree/master/springboot2_neo4j

6.參考

參考位址:

https://baike.baidu.com/item/Neo4j/9952114?fr=aladdin