站长之家源码下载/视频剪辑培训班学费一般多少
基于前两篇的简单实战后,本篇我们继续讲Neo4j的应用,模拟公司内部员工之间的关系,当然,关系可能是上下级(管理),也可能是同级(同事),甚至也有可能是其他一些特殊的关系,比如说,互相喜欢啊...etc
本文参考地址:https://spring.io/guides/gs/accessing-data-neo4j/
一、Spring-Boot目录结构图
二、先有节点(顶点)才有关系(边)
(1)创建Employee(员工)节点实体--【包含两个关系】
package com.appleyk.data.nodeentity;import java.util.Collections;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;import org.neo4j.ogm.annotation.GraphId;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Relationship;@NodeEntity
public class Employee {@GraphId private Long id;private String name;public Employee(String name) {this.name = name;}/*** Neo4j 并没有真正的双向关系,我们只有在查询的时候忽略关系的方向* 可以参考下面这个链接对neo4j的关系作出正确的理解:* https://dzone.com/articles/modelling-data-neo4j*/@Relationship(type = "同事", direction = Relationship.UNDIRECTED)//@Relationship(type = "同事")public Set<Employee> colleagues;@Relationship(type = "管理")public Set<Employee> manages;/** 指定同事关系 --->*/public void worksWith(Employee person) {if (colleagues == null) {colleagues = new HashSet<>();}colleagues.add(person);}/** 指定管理关系 --->*/public void management(Employee person) {if (manages == null) {manages = new HashSet<>();}manages.add(person);}/*** 列出该节点(Employee)的关系网*/public String toString() {/* java8新特新* Optional.ofNullable(arg) 参数可以是null * 如果值不为null,orElse方法返回Optional实例(关系)的值* Collections.emptySet():防止空指针出现* |* |* V* 当代码需要一个集合而这个集合可能不存在,此时尽量使用空集合而不是null*/return this.name + " 同事 => "+ Optional.ofNullable(this.colleagues).orElse(Collections.emptySet()).stream().map(person -> person.getName()).collect(Collectors.toList())+ " 管理 => "+ Optional.ofNullable(this.manages).orElse(Collections.emptySet()).stream().map(person -> person.getName()).collect(Collectors.toList());}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
(2)创建Employee增删改查接口
package com.appleyk.data.Repository;import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.stereotype.Repository;import com.appleyk.data.nodeentity.Employee;@Repository
public interface EmployeeRepository extends GraphRepository<Employee>{Employee findByName(String name);
}
三、Spring-Boot启动时即创建节点及节点之间的关系
(1)
package com.appleyk;import java.util.Arrays;
import java.util.List;import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;import com.appleyk.data.Repository.EmployeeRepository;
import com.appleyk.data.nodeentity.Employee;/*** * 下面是一个典型的结构:* * com +- example +- myproject +- Application.java --* 注意这个位置,习惯性的放在项目的一开始,也就是根包的第一层 | + - domain | +- Customer.java | +-* CustomerRepository.java | + - service | +- CustomerService.java | + - web +-* CustomerController.java* * * 文件将声明 main 方法, 还有基本的 @Configuration* * @author yukun24@126.com* @date 2017年12月1日08:46:41*/@SpringBootApplication // same as @Configuration @EnableAutoConfiguration @ComponentScan
public class Application extends SpringBootServletInitializer{/*** SpringApplication类提供了一种从main()方法启动Spring应用的便捷方式。 在很多情况下, 你只需委托给* SpringApplication.run这个静态方法:* * @param args*/public static void main(String[] args) {SpringApplication.run(Application.class, args);}@Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder application) {return application.sources(Application.class);}/*** Spring-Boot启动的时候,加载、创建、初始化数据* @param personRepository* @return*/@BeanCommandLineRunner demo(EmployeeRepository employeeRepository) { return args -> {//先删除Employees节点,再创建employeeRepository.deleteAll();Employee boss = new Employee("总裁");Employee manager= new Employee("项目经理");Employee p1 = new Employee("员工1");Employee p2 = new Employee("员工2");List<Employee> team = Arrays.asList(boss,manager,p1,p2);System.err.println("连接neo4j图库没创建关系节点之前...");team.stream().forEach(person -> System.err.println("\t" + person.toString()));employeeRepository.save(boss);employeeRepository.save(manager);employeeRepository.save(p1);employeeRepository.save(p2);boss = employeeRepository.findByName(boss.getName());/* * Boss管理经理(一级直属关系)*/boss.management(manager);/** 同时 Boss和其他人是同事关系,反之亦成立*/boss.worksWith(manager);boss.worksWith(p1);boss.worksWith(p2);//建立关系employeeRepository.save(boss);/* * 经理管理员工1和2(直接关系) * 先查节点,再添加关系(边)*/manager = employeeRepository.findByName(manager.getName());manager.management(p1);manager.management(p2);/** 由于上面我们已经知道了Boss和经理是同事,反之亦然,下面只添加经理和其他人的同事关系*/manager.worksWith(p1);manager.worksWith(p2);employeeRepository.save(manager);/* * 员工1和员工2是同事关系,此层关系不考虑方向,因此创建一个就Ok*/p1 = employeeRepository.findByName(p1.getName());p1.worksWith(p2);employeeRepository.save(p1);System.out.println("创建关系节点之后,通过人名查找节点查询节点信息...");team.stream().forEach(person -> System.out.println("\t" + employeeRepository.findByName(person.getName()).toString()));};}}
(2)启动Spring-Boot
(3)Neo4j图库-- Employee员工关系图谱查询(ALL)
四、查询关系(findByName)
(1)
package com.appleyk.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import com.appleyk.data.Repository.EmployeeRepository;
import com.appleyk.data.nodeentity.Employee;
import com.appleyk.result.ResponseMessage;
import com.appleyk.result.ResponseResult;@RestController
@RequestMapping("/rest/v1.0.1/database/employee")
public class EmployeeController {@AutowiredEmployeeRepository employeeRepository;@RequestMapping("/get")public ResponseResult GetEmployees(@RequestParam(value = "name") String name) {Employee employee = employeeRepository.findByName(name);if (employee != null) {/** 打印下name的关系,以下关系!=null,就是一个set集合,集合未做处理!*/System.out.println(employee.getManages());System.out.println("========上管理【" + employee.getName() + "】下同事============");System.out.println(employee.getColleagues());return new ResponseResult(ResponseMessage.OK);}return new ResponseResult(ResponseMessage.INTERNAL_SERVER_ERROR);}
}
(2)
(3)
五、项目GitHub地址
SpringBoot集成neo4j实现关系网创建和查询