Neo4j+SpringBoot实现节点以及关系的增删改查(Spring Data Neo4j)

公司让学习一下Neo4j在SpringBoot框架下的使用,我知道有个Spring DATA Neo4J,在网上找了很多教程,有些地方让我困惑了很久,所以记下来希望能给后面学习的伙伴一些帮助。

先上效果图:

效果.png

一、开发环境

IDE:idea

JDK:1.8

先搭建一个普通的SpringBoot项目,然后导入依赖。

yml配置:


spring:

  data:

    neo4j:

      uri: bolt://localhost:7687

      username: neo4j

      password: cldev

pom.xml如下:


<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-parent</artifactId>

        <version>2.3.2.RELEASE</version>

        <relativePath/> <!-- lookup parent from repository -->

    </parent>

    <groupId>com.example</groupId>

    <artifactId>neo4jdemo</artifactId>

    <version>0.0.1-SNAPSHOT</version>

    <name>neo4jdemo</name>

    <description>Demo project for Spring Boot</description>

    <properties>

        <java.version>1.8</java.version>

    </properties>

    <dependencies>

        <!--Neo4j相关-->

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-data-neo4j</artifactId>

        </dependency>

        <dependency>

            <groupId>org.neo4j</groupId>

            <artifactId>neo4j-ogm-core</artifactId>

            <version>3.2.14</version>

        </dependency>

        <dependency>

            <groupId>org.springframework.data</groupId>

            <artifactId>spring-data-neo4j</artifactId>

            <version>5.3.2.RELEASE</version>

        </dependency>

        <!--Json处理 @JsonIdentityInfo(generator= JSOGGenerator.class)用到-->

        <dependency>

            <groupId>com.voodoodyne.jackson.jsog</groupId>

            <artifactId>jackson-jsog</artifactId>

            <version>1.1</version>

            <scope>compile</scope>

        </dependency>

        <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>

            <exclusions>

                <exclusion>

                    <groupId>org.junit.vintage</groupId>

                    <artifactId>junit-vintage-engine</artifactId>

                </exclusion>

            </exclusions>

        </dependency>

    </dependencies>

    <build>

        <plugins>

            <plugin>

                <groupId>org.springframework.boot</groupId>

                <artifactId>spring-boot-maven-plugin</artifactId>

            </plugin>

        </plugins>

    </build>

</project>

项目目录结构

二、代码部分

为了简单,本项目节点只设置一种类型(User),实现的关系的某一个User知道另一User,关系(Know)。

首先编写User节点类(UserNode .java):

package com.example.neo4jdemo.entity.node;

import com.fasterxml.jackson.annotation.JsonIdentityInfo;

import com.voodoodyne.jackson.jsog.JSOGGenerator;

import org.neo4j.ogm.annotation.*;

import java.util.HashSet;

import java.util.Set;

@JsonIdentityInfo(generator= JSOGGenerator.class)

@NodeEntity(label = "User")

public class UserNode {

    @Id

    @GeneratedValue

    private Long nodeId;

    @Property(name = "name")

    private String name;

    @Property(name = "age")

    private int age;

    @Property(name = "sex")

    private String sex;

    /*注意这个地方:并不是说加了这个注解,然后下面实现了addKnows这个方法在以后调用addKnows

    就可以实现关系的增加,这是不对的,我看了很多教程没有说明。这个addKnows方法,只有在节点未被

    添加之前,调用该方法添加关系,然后再调用UserService中的create方法,这样关系才会同时被添加到图

    数据库中。如果想实现两个已有节点之间增加关系,需要单独实现*/

    @Relationship(type = "know" ,direction = Relationship.OUTGOING)

    private Set<UserNode> knows = new HashSet<>();

    public Long getNodeId() {

        return nodeId;

    }

    public void setNodeId(Long nodeId) {

        this.nodeId = nodeId;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public int getAge() {

        return age;

    }

    public void setAge(int age) {

        this.age = age;

    }

    public String getSex() {

        return sex;

    }

    public void setSex(String sex) {

        this.sex = sex;

    }

    public Set<UserNode> getKnows() {

        return knows;

    }

    public void setKnows(Set<UserNode> knows) {

        this.knows = knows;

    }

    public Boolean addKnows(UserNode to){

        return this.knows.add(to);

    }

    @Override

    public String toString() {

        return "UserNode{" +

                "nodeId=" + nodeId +

                ", name='" + name + '\'' +

                ", age=" + age +

                ", sex='" + sex + '\'' +

                '}';

    }

    public UserNode() {}

}

关系类(Know.java)

package com.example.neo4jdemo.entity.relationship;

import com.example.neo4jdemo.entity.node.UserNode;

import com.fasterxml.jackson.annotation.JsonIdentityInfo;

import com.voodoodyne.jackson.jsog.JSOGGenerator;

import org.neo4j.ogm.annotation.*;

/**

* @program: neo4jdemo

* @description: 知道关系类

* @author: chen

* @create: 2020-07-27

**/

@JsonIdentityInfo(generator= JSOGGenerator.class)

@RelationshipEntity(type = "know")

public class Know  {

    @Id

    @GeneratedValue

    private Long id;

    @StartNode

    private UserNode from;

    @EndNode

    private UserNode to;

    public Long getId() {

        return id;

    }

    public void setId(Long id) {

        this.id = id;

    }

    public UserNode getFrom() {

        return from;

    }

    public void setFrom(UserNode from) {

        this.from = from;

    }

    public UserNode getTo() {

        return to;

    }

    public void setTo(UserNode to) {

        this.to = to;

    }

    public Know() {

    }

    public Know(UserNode from, UserNode to) {

        this.from = from;

        this.to = to;

    }

    @Override

    public String toString() {

        return "Know{" +

                "id=" + id +

                ", from=" + from +

                ", to=" + to +

                '}';

    }

}

KnowRepository.java

package com.example.neo4jdemo.repository;

import com.example.neo4jdemo.entity.relationship.Know;

import org.springframework.data.neo4j.annotation.Query;

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

import org.springframework.data.repository.query.Param;

/**

* @program: neo4jdemo

* @description: 知道关系接口类

* @author: chen

* @create: 2020-07-27

**/

public interface KnowRepository extends Neo4jRepository<Know,Long> {

    @Query("MATCH (fromNode) WHERE id(fromNode) = {fromId} MATCH (toNode) WHERE id(toNode) = {toId} MATCH (fromNode)-[r]->(toNode) DELETE r")

    void deleteByNodeId(@Param(value = "fromId") long fromId,@Param(value = "toId") long toId);

}

UserRepository.java

基础的增删改查Spring Data Neo4j已经封装好在Neo4jRepository里面了。


package com.example.neo4jdemo.repository;

import com.example.neo4jdemo.entity.node.UserNode;

import org.springframework.data.neo4j.annotation.Query;

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

import org.springframework.data.repository.query.Param;

import org.springframework.stereotype.Repository;

@Repository

public interface UserRepository extends Neo4jRepository<UserNode,Long> {

//    @Query("MATCH (n:User) RETURN n ")

//    List<UserNode> getUserNodeList();

//

//    @Query("create (n:User{name:{name},age:{age},sex:{sex}}) RETURN n ")

//    UserNode addUserNode(@Param("name") String name, @Param("age")int age, @Param("sex") String sex);

    @Query("MATCH (n) WHERE id(n) = :#{#userNode.nodeId} SET n.name = :#{#userNode.name},n.age = :#{#userNode.age},n.sex = :#{#userNode.sex} RETURN n")

    UserNode updateByNode(@Param("userNode") UserNode userNode);

}

UserService.java

package com.example.neo4jdemo.service;

import com.example.neo4jdemo.entity.node.UserNode;

import com.example.neo4jdemo.entity.relationship.Know;

import java.util.List;

import java.util.Optional;

public interface UserService {

    /**

    * @Description: 添加user节点

    * @Params: [UserNode]

    * @return: int

    * @Author: chen

    * @Date: 2020/7/27

    */

    UserNode create(UserNode userNode);

    /**

    * @Description: 删除

    * @Author: chen

    * @Date: 2020/7/27

    */

    void deleteById(Long id);

    /**

    * @Description: 查询

    * @Author: chen

    * @Date: 2020/7/27

    * @return

    */

    Optional<UserNode> findById(long id);

    /**

    * @Description: 获取所有User节点

    * @Params: null

    * @return: List

    * @Author: chen

    * @Date: 2020/7/27

    */

    List<UserNode> findAll();

    /**

    * @Description: 增加“知道”关系

    * @Author: chen

    * @Date: 2020/7/27

    */

    Know addIKnows(UserNode fromNode, UserNode toNode);

    UserNode updateByNode(UserNode userNode);

    void deleteKnowByNodeId(long fromId,long toId);

}

UserServiceImpl.java

package com.example.neo4jdemo.service.impl;

import com.example.neo4jdemo.entity.node.UserNode;

import com.example.neo4jdemo.entity.relationship.Know;

import com.example.neo4jdemo.repository.KnowRepository;

import com.example.neo4jdemo.repository.UserRepository;

import com.example.neo4jdemo.service.UserService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import java.util.List;

import java.util.Optional;

@Service

public class UserServiceImpl implements UserService {

    @Autowired

    private UserRepository userRepository;

    @Autowired

    private KnowRepository knowRepository;

    @Override

    public UserNode create(UserNode userNode) {

        return userRepository.save(userNode);

    }

    @Override

    public void deleteById(Long id) {

        userRepository.deleteById(id);

    }

    @Override

    public Optional<UserNode> findById(long id) {

        return userRepository.findById(id);

    }

    @Override

    public List<UserNode> findAll() {

        return (List<UserNode>) userRepository.findAll();

    }

    @Override

    public Know addIKnows(UserNode fromNode, UserNode toNode) {

        Know newKnow = new Know(fromNode,toNode);

        return knowRepository.save(newKnow);

    }

    @Override

    public UserNode updateByNode(UserNode userNode) {

        return userRepository.updateByNode(userNode);

    }

    @Override

    public void deleteKnowByNodeId(long fromId, long toId) {

        knowRepository.deleteByNodeId(fromId,toId);

    }

}

UserController.java

package com.example.neo4jdemo.controller;

import com.example.neo4jdemo.entity.node.UserNode;

import com.example.neo4jdemo.entity.relationship.Know;

import com.example.neo4jdemo.service.UserService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.*;

import java.util.List;

import java.util.Optional;

/**

* @program: neo4jdemo

* @description: 控制层

* @author: chen

* @create: 2020-07-27

**/

@RestController

public class UserController {

    @Autowired

    private UserService userService;

    /**

    * @Description: 添加节点

    * @Author: chen

    * @Date: 2020/7/27

    */

    @RequestMapping(path = "/add", method = RequestMethod.POST)

    public UserNode addUserNode(@RequestBody UserNode userNode) {

        return userService.create(userNode);

    }

    /**

    * @Description: 根据id删除

    * @Author: chen

    * @Date: 2020/7/27

    */

    @RequestMapping(path = "/delete", method = RequestMethod.POST)

    public int delUserNodeById(@RequestParam(value = "id") long id) {

        userService.deleteById(id);

        System.out.println(id);

        return 1;

    }

    /**

    * @Description: 根据id更新

    * @Author: chen

    * @Date: 2020/7/27

    */

    @RequestMapping(path = "/update", method = RequestMethod.POST)

    public UserNode updateUserNodeByNode(@RequestBody UserNode userNode) {

        return userService.updateByNode(userNode);

    }

    @RequestMapping(path = "/get", method = RequestMethod.GET)

    public UserNode getUserNodeById(@RequestParam(value = "id") long id) {

        Optional<UserNode> optionalUserNode =  userService.findById(id);

        if(optionalUserNode.isPresent()){

            return optionalUserNode.get();

        }else{

            return null;

        }

    }

    /**

    * @Description: 查找所有节点

    * @Author: chen

    * @Date: 2020/7/27

    */

    @RequestMapping(path = "/list", method = RequestMethod.GET)

    public List<UserNode> getUserNodeList() {

        return userService.findAll();

    }

    @RequestMapping(path = "/addKnows", method = RequestMethod.POST)

    public Know addKnowsById(@RequestParam(value = "from") long fromId, @RequestParam(value = "to") long toId) {

        Optional<UserNode> fromOpt =  userService.findById(fromId);

        Optional<UserNode> toOpt =  userService.findById(toId);

        if(fromOpt.isPresent()&&toOpt.isPresent()){

            return userService.addIKnows(fromOpt.get(),toOpt.get());

        }else{

            return null;

        }

    }

    @RequestMapping(path = "/delKnows", method = RequestMethod.POST)

    public String deleteKnowsByNodeId(@RequestParam(value = "from") long fromId, @RequestParam(value = "to") long toId) {

        Optional<UserNode> fromOpt =  userService.findById(fromId);

        Optional<UserNode> toOpt =  userService.findById(toId);

        if(fromOpt.isPresent()&&toOpt.isPresent()){

            userService.deleteKnowByNodeId(fromId,toId);

            return "ok";

        }else{

            return "false";

        }

    }

}

Neo4jConfig.java 我也不知道干啥的

package com.example.neo4jdemo.config;

import org.springframework.context.annotation.Configuration;

import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;

import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration

@EnableNeo4jRepositories(basePackages = "com.example.neo4jdemo.repository")

@EnableTransactionManagement // 激活SDN隐式事务

public class Neo4jConfig {

}

重点就是User中的那段注释,是我困扰了很久的问题,希望大家能够避坑。有什么问题可以留言。

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值