Spring boot + neo4j ☞ create a multi-point network

Based on the simple practice of the first two articles, we will continue to talk about the application of Neo4j, simulating the relationship between employees in the company. Of course, the relationship may be the superior and subordinate (Management), the same level (colleagues), or even some other special relationships, such as, like each other... etc


Reference address: https://spring.io/guides/gs/accessing-data-neo4j/



1, Spring boot directory structure chart






2, Nodes (vertices) before relationships (edges)



(1) Create Employee node entity - include two relationships


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 There is no real two-way relationship, we only ignore the direction of the relationship when querying
	 * You can refer to the following link to make a correct understanding of the relationship between neo4j:
	 * https://dzone.com/articles/modelling-data-neo4j
	 */
	@Relationship(type = "Colleague", direction = Relationship.UNDIRECTED)
	//@Relationship(type = "colleague")
	public Set<Employee> colleagues;
	
	@Relationship(type = "Administration")
	public Set<Employee> manages;

	/*
	 * Specify colleague relationship -- >
	 */
	public void worksWith(Employee person) {
		if (colleagues == null) {
			colleagues = new HashSet<>();
		}
		colleagues.add(person);
	}
	
	/*
	 * Specify management relationship -- >
	 */
	public void management(Employee person) {
		if (manages == null) {
			manages = new HashSet<>();
		}
		manages.add(person);
	}
	

	/**
	 * List the network of this node (Employee)
	 */
	public String toString() {

		/* java8 New, special and new
		 * Optional.ofNullable(arg) Parameter can be null 
		 * If the value is not null, the orElse method returns the value of the Optional instance (relationship)
		 * Collections.emptySet():Prevent null pointer
		 *            |
		 *            |
		 *            V
		 * When the code needs a collection and the collection may not exist, try to use an empty collection instead of null
		 */
		return this.name + " Colleague => "
				+ Optional.ofNullable(this.colleagues).orElse(
						Collections.emptySet()).stream().map(
								person -> person.getName()).collect(Collectors.toList())
				+ " Administration => "
						+ 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) Create Employee add, delete, modify and query interface


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);
}




3, When spring boot is started, the relationship between nodes is created



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

/**
 * 
 * Here is a typical structure:
 * 
 * com +- example +- myproject +- Application.java --
 * Note that this position is habitually placed at the beginning of the project, that is, the first layer of the root package - domain + - customer. Java |+-
 * CustomerRepository.java | + - service | +- CustomerService.java | + - web +-
 * CustomerController.java
 * 
 * 
 * The file will declare the main method and the basic @ Configuration
 * 
 * @author yukun24@126.com
 * @date 2017 December 1, 2008 08:46:41
 */

@SpringBootApplication // same as @Configuration @EnableAutoConfiguration  @ComponentScan		
public class Application extends SpringBootServletInitializer{

	/**
	 * SpringApplication Class provides a convenient way to start Spring applications from the main() method. In many cases, you just delegate
	 * SpringApplication.run This static method:
	 * 
	 * @param args
	 */

	public static void main(String[] args) {
        		
		SpringApplication.run(Application.class, args);
			
	}
	
	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
		return application.sources(Application.class);
	}
	
	
	/**
	 * Spring-Boot Loading, creating and initializing data during startup
	 * @param personRepository
	 * @return
	 */
	@Bean
	CommandLineRunner demo(EmployeeRepository employeeRepository) {	
		return args -> {

			//Delete the Employees node before creating
			employeeRepository.deleteAll();

			Employee boss = new Employee("CEO");
			Employee manager= new Employee("project manager");
			Employee p1 = new Employee("Employee 1");
			Employee p2 = new Employee("Employee 2");

			List<Employee> team = Arrays.asList(boss,manager,p1,p2);

			System.err.println("Connect neo4j Before the graph base creates the relation node...");

			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 Management Manager (Level 1 direct relationship)
			 */
			boss.management(manager);
			
			/*
			 * At the same time, Boss and others are colleagues, and vice versa
			 */
			boss.worksWith(manager);
			boss.worksWith(p1);
			boss.worksWith(p2);
			//Building relationships
			employeeRepository.save(boss);

			
			/* 
			 * Managers manage employees 1 and 2 (direct relationship) 
			 * First check the node, then add the relationship (edge)
			 */
			manager = employeeRepository.findByName(manager.getName());
			manager.management(p1);
			manager.management(p2);
			
			/*
			 * As we know above that Boss and manager are colleagues, and vice versa, only the colleague relationship between manager and other people is added below
			 */
			manager.worksWith(p1);
			manager.worksWith(p2);
			
			employeeRepository.save(manager);
			
			/* 
			 * Employee 1 and employee 2 are colleague relationships, which do not consider direction, so create an Ok relationship
			 */
			p1 = employeeRepository.findByName(p1.getName());
			p1.worksWith(p2);
			employeeRepository.save(p1);

			System.out.println("After creating a relationship node, query the node information by looking up the node name...");
			team.stream().forEach(person -> System.out.println(
					"\t" + employeeRepository.findByName(person.getName()).toString()));
		};
	}

}



(2) Start spring boot










(3) Neo4j chart Library - Employee employee relationship map query (ALL)







4, Query relationship (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 {

	@Autowired
	EmployeeRepository employeeRepository;

	@RequestMapping("/get")
	public ResponseResult GetEmployees(@RequestParam(value = "name") String name) {
		Employee employee = employeeRepository.findByName(name);

		if (employee != null) {

			/*
			 * Print the relationship of name, the following relationship! =null is a set set. The set has not been processed!
			 */
			System.out.println(employee.getManages());
			System.out.println("========Upper management[" + employee.getName() + "]Next colleague============");
			System.out.println(employee.getColleagues());

			return new ResponseResult(ResponseMessage.OK);
		}

		return new ResponseResult(ResponseMessage.INTERNAL_SERVER_ERROR);

	}
}




(2)






(3)




Tags: Java Spring network REST

Posted on Tue, 05 May 2020 02:52:21 -0400 by JimBadger