From c4b5e0c8e3461831d4a9c2e18e985a8057edae16 Mon Sep 17 00:00:00 2001
From: "Yangkai.Shen" <237497819@qq.com>
Date: Mon, 24 Dec 2018 20:30:16 +0800
Subject: [PATCH] =?UTF-8?q?:sparkles:=20spring-boot-demo-neo4j=20=E5=AE=8C?=
=?UTF-8?q?=E6=88=90?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
spring-boot-demo-neo4j/README.md | 15 ++
spring-boot-demo-neo4j/pom.xml | 16 ++
.../neo4j/config/CustomIdStrategy.java | 24 +++
.../xkcoding/neo4j/constants/NeoConsts.java | 37 ++++
.../java/com/xkcoding/neo4j/model/Class.java | 50 ++++++
.../java/com/xkcoding/neo4j/model/Lesson.java | 50 ++++++
.../com/xkcoding/neo4j/model/Student.java | 60 +++++++
.../com/xkcoding/neo4j/model/Teacher.java | 41 +++++
.../payload/ClassmateInfoGroupByLesson.java | 34 ++++
.../neo4j/repository/ClassRepository.java | 29 +++
.../neo4j/repository/LessonRepository.java | 20 +++
.../neo4j/repository/StudentRepository.java | 48 +++++
.../neo4j/repository/TeacherRepository.java | 20 +++
.../xkcoding/neo4j/service/NeoService.java | 166 ++++++++++++++++++
.../src/main/resources/application.yml | 7 +
.../java/com/xkcoding/neo4j/Neo4jTest.java | 82 +++++++++
16 files changed, 699 insertions(+)
create mode 100644 spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/config/CustomIdStrategy.java
create mode 100644 spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/constants/NeoConsts.java
create mode 100644 spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/model/Class.java
create mode 100644 spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/model/Lesson.java
create mode 100644 spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/model/Student.java
create mode 100644 spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/model/Teacher.java
create mode 100644 spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/payload/ClassmateInfoGroupByLesson.java
create mode 100644 spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/repository/ClassRepository.java
create mode 100644 spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/repository/LessonRepository.java
create mode 100644 spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/repository/StudentRepository.java
create mode 100644 spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/repository/TeacherRepository.java
create mode 100644 spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/service/NeoService.java
create mode 100644 spring-boot-demo-neo4j/src/test/java/com/xkcoding/neo4j/Neo4jTest.java
diff --git a/spring-boot-demo-neo4j/README.md b/spring-boot-demo-neo4j/README.md
index 4d7ba48..26931d3 100644
--- a/spring-boot-demo-neo4j/README.md
+++ b/spring-boot-demo-neo4j/README.md
@@ -1 +1,16 @@
# spring-boot-demo-neo4j
+
+> 此 demo 主要演示了 Spring Boot 如何集成Neo4j操作图数据库,实现一个校园人物关系网。
+
+## 注意
+
+作者编写本demo时,Neo4j 版本为 `3.5.0`,使用 docker 运行,下面是所有步骤:
+
+1. 下载镜像:`docker pull neo4j:3.5.0`
+2. 运行容器:`docker run -d -p 7474:7474 -p 7687:7687 --name neo4j-3.5.0 neo4j:3.5.0`
+3. 停止容器:`docker stop neo4j-3.5.0`
+4. 启动容器:`docker start neo4j-3.5.0`
+5. 浏览器 http://localhost:7474/ 访问 neo4j 管理后台,初始账号/密码 neo4j/neo4j,会要求修改初始化密码,我们修改为 neo4j/admin
+
+
+
diff --git a/spring-boot-demo-neo4j/pom.xml b/spring-boot-demo-neo4j/pom.xml
index c163711..0526dee 100644
--- a/spring-boot-demo-neo4j/pom.xml
+++ b/spring-boot-demo-neo4j/pom.xml
@@ -38,6 +38,22 @@
spring-boot-starter-test
test
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+ cn.hutool
+ hutool-all
+
+
+
+ com.google.guava
+ guava
+
diff --git a/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/config/CustomIdStrategy.java b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/config/CustomIdStrategy.java
new file mode 100644
index 0000000..5cc8778
--- /dev/null
+++ b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/config/CustomIdStrategy.java
@@ -0,0 +1,24 @@
+package com.xkcoding.neo4j.config;
+
+import cn.hutool.core.util.IdUtil;
+import org.neo4j.ogm.id.IdStrategy;
+
+/**
+ *
+ * 自定义主键策略
+ *
+ *
+ * @package: com.xkcoding.neo4j.config
+ * @description: 自定义主键策略
+ * @author: yangkai.shen
+ * @date: Created in 2018-12-24 14:40
+ * @copyright: Copyright (c) 2018
+ * @version: V1.0
+ * @modified: yangkai.shen
+ */
+public class CustomIdStrategy implements IdStrategy {
+ @Override
+ public Object generateId(Object o) {
+ return IdUtil.fastUUID();
+ }
+}
diff --git a/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/constants/NeoConsts.java b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/constants/NeoConsts.java
new file mode 100644
index 0000000..0ea6f9d
--- /dev/null
+++ b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/constants/NeoConsts.java
@@ -0,0 +1,37 @@
+package com.xkcoding.neo4j.constants;
+
+/**
+ *
+ * 常量池
+ *
+ *
+ * @package: com.xkcoding.neo4j.constants
+ * @description: 常量池
+ * @author: yangkai.shen
+ * @date: Created in 2018-12-24 14:45
+ * @copyright: Copyright (c) 2018
+ * @version: V1.0
+ * @modified: yangkai.shen
+ */
+public interface NeoConsts {
+ /**
+ * 关系:班级拥有的学生
+ */
+ String R_STUDENT_OF_CLASS = "R_STUDENT_OF_CLASS";
+
+ /**
+ * 关系:班级的班主任
+ */
+ String R_BOSS_OF_CLASS = "R_BOSS_OF_CLASS";
+
+ /**
+ * 关系:课程的老师
+ */
+ String R_TEACHER_OF_LESSON = "R_TEACHER_OF_LESSON";
+
+ /**
+ * 关系:学生选的课
+ */
+ String R_LESSON_OF_STUDENT = "R_LESSON_OF_STUDENT";
+
+}
diff --git a/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/model/Class.java b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/model/Class.java
new file mode 100644
index 0000000..8af1f66
--- /dev/null
+++ b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/model/Class.java
@@ -0,0 +1,50 @@
+package com.xkcoding.neo4j.model;
+
+import com.xkcoding.neo4j.config.CustomIdStrategy;
+import com.xkcoding.neo4j.constants.NeoConsts;
+import lombok.*;
+import org.neo4j.ogm.annotation.GeneratedValue;
+import org.neo4j.ogm.annotation.Id;
+import org.neo4j.ogm.annotation.NodeEntity;
+import org.neo4j.ogm.annotation.Relationship;
+
+/**
+ *
+ * 班级节点
+ *
+ *
+ * @package: com.xkcoding.neo4j.model
+ * @description: 班级节点
+ * @author: yangkai.shen
+ * @date: Created in 2018-12-24 14:44
+ * @copyright: Copyright (c) 2018
+ * @version: V1.0
+ * @modified: yangkai.shen
+ */
+@Data
+@NoArgsConstructor
+@RequiredArgsConstructor(staticName = "of")
+@AllArgsConstructor
+@Builder
+@NodeEntity
+public class Class {
+ /**
+ * 主键
+ */
+ @Id
+ @GeneratedValue(strategy = CustomIdStrategy.class)
+ private String id;
+
+ /**
+ * 班级名称
+ */
+ @NonNull
+ private String name;
+
+ /**
+ * 班级的班主任
+ */
+ @Relationship(NeoConsts.R_BOSS_OF_CLASS)
+ @NonNull
+ private Teacher boss;
+}
diff --git a/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/model/Lesson.java b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/model/Lesson.java
new file mode 100644
index 0000000..8d96d42
--- /dev/null
+++ b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/model/Lesson.java
@@ -0,0 +1,50 @@
+package com.xkcoding.neo4j.model;
+
+import com.xkcoding.neo4j.config.CustomIdStrategy;
+import com.xkcoding.neo4j.constants.NeoConsts;
+import lombok.*;
+import org.neo4j.ogm.annotation.GeneratedValue;
+import org.neo4j.ogm.annotation.Id;
+import org.neo4j.ogm.annotation.NodeEntity;
+import org.neo4j.ogm.annotation.Relationship;
+
+/**
+ *
+ * 课程节点
+ *
+ *
+ * @package: com.xkcoding.neo4j.model
+ * @description: 课程节点
+ * @author: yangkai.shen
+ * @date: Created in 2018-12-24 14:55
+ * @copyright: Copyright (c) 2018
+ * @version: V1.0
+ * @modified: yangkai.shen
+ */
+@Data
+@NoArgsConstructor
+@RequiredArgsConstructor(staticName = "of")
+@AllArgsConstructor
+@Builder
+@NodeEntity
+public class Lesson {
+ /**
+ * 主键,自定义主键策略,使用UUID生成
+ */
+ @Id
+ @GeneratedValue(strategy = CustomIdStrategy.class)
+ private String id;
+
+ /**
+ * 课程名称
+ */
+ @NonNull
+ private String name;
+
+ /**
+ * 任教老师
+ */
+ @Relationship(NeoConsts.R_TEACHER_OF_LESSON)
+ @NonNull
+ private Teacher teacher;
+}
diff --git a/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/model/Student.java b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/model/Student.java
new file mode 100644
index 0000000..4ce6a85
--- /dev/null
+++ b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/model/Student.java
@@ -0,0 +1,60 @@
+package com.xkcoding.neo4j.model;
+
+import com.xkcoding.neo4j.config.CustomIdStrategy;
+import com.xkcoding.neo4j.constants.NeoConsts;
+import lombok.*;
+import org.neo4j.ogm.annotation.GeneratedValue;
+import org.neo4j.ogm.annotation.Id;
+import org.neo4j.ogm.annotation.NodeEntity;
+import org.neo4j.ogm.annotation.Relationship;
+
+import java.util.List;
+
+/**
+ *
+ * 学生节点
+ *
+ *
+ * @package: com.xkcoding.neo4j.model
+ * @description: 学生节点
+ * @author: yangkai.shen
+ * @date: Created in 2018-12-24 14:38
+ * @copyright: Copyright (c) 2018
+ * @version: V1.0
+ * @modified: yangkai.shen
+ */
+@Data
+@NoArgsConstructor
+@RequiredArgsConstructor(staticName = "of")
+@AllArgsConstructor
+@Builder
+@NodeEntity
+public class Student {
+ /**
+ * 主键,自定义主键策略,使用UUID生成
+ */
+ @Id
+ @GeneratedValue(strategy = CustomIdStrategy.class)
+ private String id;
+
+ /**
+ * 学生姓名
+ */
+ @NonNull
+ private String name;
+
+ /**
+ * 学生选的所有课程
+ */
+ @Relationship(NeoConsts.R_LESSON_OF_STUDENT)
+ @NonNull
+ private List lessons;
+
+ /**
+ * 学生所在班级
+ */
+ @Relationship(NeoConsts.R_STUDENT_OF_CLASS)
+ @NonNull
+ private Class clazz;
+
+}
diff --git a/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/model/Teacher.java b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/model/Teacher.java
new file mode 100644
index 0000000..968ddb1
--- /dev/null
+++ b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/model/Teacher.java
@@ -0,0 +1,41 @@
+package com.xkcoding.neo4j.model;
+
+import com.xkcoding.neo4j.config.CustomIdStrategy;
+import lombok.*;
+import org.neo4j.ogm.annotation.GeneratedValue;
+import org.neo4j.ogm.annotation.Id;
+import org.neo4j.ogm.annotation.NodeEntity;
+
+/**
+ *
+ * 教师节点
+ *
+ *
+ * @package: com.xkcoding.neo4j.model
+ * @description: 教师节点
+ * @author: yangkai.shen
+ * @date: Created in 2018-12-24 14:54
+ * @copyright: Copyright (c) 2018
+ * @version: V1.0
+ * @modified: yangkai.shen
+ */
+@Data
+@NoArgsConstructor
+@RequiredArgsConstructor(staticName = "of")
+@AllArgsConstructor
+@Builder
+@NodeEntity
+public class Teacher {
+ /**
+ * 主键,自定义主键策略,使用UUID生成
+ */
+ @Id
+ @GeneratedValue(strategy = CustomIdStrategy.class)
+ private String id;
+
+ /**
+ * 教师姓名
+ */
+ @NonNull
+ private String name;
+}
diff --git a/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/payload/ClassmateInfoGroupByLesson.java b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/payload/ClassmateInfoGroupByLesson.java
new file mode 100644
index 0000000..b5a156c
--- /dev/null
+++ b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/payload/ClassmateInfoGroupByLesson.java
@@ -0,0 +1,34 @@
+package com.xkcoding.neo4j.payload;
+
+import com.xkcoding.neo4j.model.Student;
+import lombok.Data;
+import org.springframework.data.neo4j.annotation.QueryResult;
+
+import java.util.List;
+
+/**
+ *
+ * 按照课程分组的同学关系
+ *
+ *
+ * @package: com.xkcoding.neo4j.payload
+ * @description: 按照课程分组的同学关系
+ * @author: yangkai.shen
+ * @date: Created in 2018-12-24 19:18
+ * @copyright: Copyright (c) 2018
+ * @version: V1.0
+ * @modified: yangkai.shen
+ */
+@Data
+@QueryResult
+public class ClassmateInfoGroupByLesson {
+ /**
+ * 课程名称
+ */
+ private String lessonName;
+
+ /**
+ * 学生信息
+ */
+ private List students;
+}
diff --git a/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/repository/ClassRepository.java b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/repository/ClassRepository.java
new file mode 100644
index 0000000..e8c59b9
--- /dev/null
+++ b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/repository/ClassRepository.java
@@ -0,0 +1,29 @@
+package com.xkcoding.neo4j.repository;
+
+import com.xkcoding.neo4j.model.Class;
+import org.springframework.data.neo4j.repository.Neo4jRepository;
+
+import java.util.Optional;
+
+/**
+ *
+ * 班级节点Repository
+ *
+ *
+ * @package: com.xkcoding.neo4j.repository
+ * @description: 班级节点Repository
+ * @author: yangkai.shen
+ * @date: Created in 2018-12-24 15:05
+ * @copyright: Copyright (c) 2018
+ * @version: V1.0
+ * @modified: yangkai.shen
+ */
+public interface ClassRepository extends Neo4jRepository {
+ /**
+ * 根据班级名称查询班级信息
+ *
+ * @param name 班级名称
+ * @return 班级信息
+ */
+ Optional findByName(String name);
+}
diff --git a/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/repository/LessonRepository.java b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/repository/LessonRepository.java
new file mode 100644
index 0000000..a4f7b9d
--- /dev/null
+++ b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/repository/LessonRepository.java
@@ -0,0 +1,20 @@
+package com.xkcoding.neo4j.repository;
+
+import com.xkcoding.neo4j.model.Lesson;
+import org.springframework.data.neo4j.repository.Neo4jRepository;
+
+/**
+ *
+ * 课程节点Repository
+ *
+ *
+ * @package: com.xkcoding.neo4j.repository
+ * @description: 课程节点Repository
+ * @author: yangkai.shen
+ * @date: Created in 2018-12-24 15:05
+ * @copyright: Copyright (c) 2018
+ * @version: V1.0
+ * @modified: yangkai.shen
+ */
+public interface LessonRepository extends Neo4jRepository {
+}
diff --git a/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/repository/StudentRepository.java b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/repository/StudentRepository.java
new file mode 100644
index 0000000..fb4dd69
--- /dev/null
+++ b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/repository/StudentRepository.java
@@ -0,0 +1,48 @@
+package com.xkcoding.neo4j.repository;
+
+import com.xkcoding.neo4j.model.Student;
+import com.xkcoding.neo4j.payload.ClassmateInfoGroupByLesson;
+import org.springframework.data.neo4j.annotation.Depth;
+import org.springframework.data.neo4j.annotation.Query;
+import org.springframework.data.neo4j.repository.Neo4jRepository;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ *
+ * 学生节点Repository
+ *
+ *
+ * @package: com.xkcoding.neo4j.repository
+ * @description: 学生节点Repository
+ * @author: yangkai.shen
+ * @date: Created in 2018-12-24 15:05
+ * @copyright: Copyright (c) 2018
+ * @version: V1.0
+ * @modified: yangkai.shen
+ */
+public interface StudentRepository extends Neo4jRepository {
+ /**
+ * 根据名称查找学生
+ *
+ * @param name 姓名
+ * @param depth 深度
+ * @return 学生信息
+ */
+ Optional findByName(String name, @Depth int depth);
+
+ /**
+ * 根据班级查询班级人数
+ *
+ * @param className 班级名称
+ * @return 班级人数
+ */
+ @Query("MATCH (s:Student)-[r:R_STUDENT_OF_CLASS]->(c:Class{name:{className}}) return count(s)")
+ Long countByClassName(@Param("className") String className);
+
+
+ @Query("match (s:Student)-[:R_LESSON_OF_STUDENT]->(l:Lesson),(l:Lesson)<-[:R_LESSON_OF_STUDENT]-(:Student) with l.name as lessonName,collect(distinct s) as students return lessonName,students")
+ List findByClassmateGroupByLesson();
+}
diff --git a/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/repository/TeacherRepository.java b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/repository/TeacherRepository.java
new file mode 100644
index 0000000..380f1ff
--- /dev/null
+++ b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/repository/TeacherRepository.java
@@ -0,0 +1,20 @@
+package com.xkcoding.neo4j.repository;
+
+import com.xkcoding.neo4j.model.Teacher;
+import org.springframework.data.neo4j.repository.Neo4jRepository;
+
+/**
+ *
+ * 教师节点Repository
+ *
+ *
+ * @package: com.xkcoding.neo4j.repository
+ * @description: 教师节点Repository
+ * @author: yangkai.shen
+ * @date: Created in 2018-12-24 15:05
+ * @copyright: Copyright (c) 2018
+ * @version: V1.0
+ * @modified: yangkai.shen
+ */
+public interface TeacherRepository extends Neo4jRepository {
+}
diff --git a/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/service/NeoService.java b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/service/NeoService.java
new file mode 100644
index 0000000..057b800
--- /dev/null
+++ b/spring-boot-demo-neo4j/src/main/java/com/xkcoding/neo4j/service/NeoService.java
@@ -0,0 +1,166 @@
+package com.xkcoding.neo4j.service;
+
+import cn.hutool.core.util.StrUtil;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.xkcoding.neo4j.model.Class;
+import com.xkcoding.neo4j.model.Lesson;
+import com.xkcoding.neo4j.model.Student;
+import com.xkcoding.neo4j.model.Teacher;
+import com.xkcoding.neo4j.payload.ClassmateInfoGroupByLesson;
+import com.xkcoding.neo4j.repository.ClassRepository;
+import com.xkcoding.neo4j.repository.LessonRepository;
+import com.xkcoding.neo4j.repository.StudentRepository;
+import com.xkcoding.neo4j.repository.TeacherRepository;
+import org.neo4j.ogm.session.Session;
+import org.neo4j.ogm.session.SessionFactory;
+import org.neo4j.ogm.transaction.Transaction;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ *
+ * NeoService
+ *
+ *
+ * @package: com.xkcoding.neo4j.service
+ * @description: NeoService
+ * @author: yangkai.shen
+ * @date: Created in 2018-12-24 15:19
+ * @copyright: Copyright (c) 2018
+ * @version: V1.0
+ * @modified: yangkai.shen
+ */
+@Service
+public class NeoService {
+ @Autowired
+ private ClassRepository classRepo;
+
+ @Autowired
+ private LessonRepository lessonRepo;
+
+ @Autowired
+ private StudentRepository studentRepo;
+
+ @Autowired
+ private TeacherRepository teacherRepo;
+
+ @Autowired
+ private SessionFactory sessionFactory;
+
+ /**
+ * 初始化数据
+ */
+ @Transactional
+ public void initData() {
+ // 初始化老师
+ Teacher akai = Teacher.of("迈特凯");
+ Teacher kakaxi = Teacher.of("旗木卡卡西");
+ Teacher zilaiye = Teacher.of("自来也");
+ Teacher gangshou = Teacher.of("纲手");
+ Teacher dashewan = Teacher.of("大蛇丸");
+ teacherRepo.save(akai);
+ teacherRepo.save(kakaxi);
+ teacherRepo.save(zilaiye);
+ teacherRepo.save(gangshou);
+ teacherRepo.save(dashewan);
+
+ // 初始化课程
+ Lesson tishu = Lesson.of("体术", akai);
+ Lesson huanshu = Lesson.of("幻术", kakaxi);
+ Lesson shoulijian = Lesson.of("手里剑", kakaxi);
+ Lesson luoxuanwan = Lesson.of("螺旋丸", zilaiye);
+ Lesson xianshu = Lesson.of("仙术", zilaiye);
+ Lesson yiliao = Lesson.of("医疗", gangshou);
+ Lesson zhouyin = Lesson.of("咒印", dashewan);
+ lessonRepo.save(tishu);
+ lessonRepo.save(huanshu);
+ lessonRepo.save(shoulijian);
+ lessonRepo.save(luoxuanwan);
+ lessonRepo.save(xianshu);
+ lessonRepo.save(yiliao);
+ lessonRepo.save(zhouyin);
+
+ // 初始化班级
+ Class three = Class.of("第三班", akai);
+ Class seven = Class.of("第七班", kakaxi);
+ classRepo.save(three);
+ classRepo.save(seven);
+
+ // 初始化学生
+ List threeClass = Lists.newArrayList(Student.of("漩涡鸣人", Lists.newArrayList(tishu, shoulijian, luoxuanwan, xianshu), seven), Student
+ .of("宇智波佐助", Lists.newArrayList(huanshu, zhouyin, shoulijian), seven), Student.of("春野樱", Lists.newArrayList(tishu, yiliao, shoulijian), seven));
+ List sevenClass = Lists.newArrayList(Student.of("李洛克", Lists.newArrayList(tishu), three), Student.of("日向宁次", Lists
+ .newArrayList(tishu), three), Student.of("天天", Lists.newArrayList(tishu), three));
+
+ studentRepo.saveAll(threeClass);
+ studentRepo.saveAll(sevenClass);
+
+ }
+
+ /**
+ * 删除数据
+ */
+ @Transactional
+ public void delete() {
+ // 使用语句删除
+ Session session = sessionFactory.openSession();
+ Transaction transaction = session.beginTransaction();
+ session.query("match (n)-[r]-() delete n,r", Maps.newHashMap());
+ session.query("match (n)-[r]-() delete r", Maps.newHashMap());
+ session.query("match (n) delete n", Maps.newHashMap());
+ transaction.commit();
+
+ // 使用 repository 删除
+ studentRepo.deleteAll();
+ classRepo.deleteAll();
+ lessonRepo.deleteAll();
+ teacherRepo.deleteAll();
+ }
+
+ /**
+ * 根据学生姓名查询所选课程
+ *
+ * @param studentName 学生姓名
+ * @param depth 深度
+ * @return 课程列表
+ */
+ public List findLessonsFromStudent(String studentName, int depth) {
+ List lessons = Lists.newArrayList();
+ studentRepo.findByName(studentName, depth).ifPresent(student -> lessons.addAll(student.getLessons()));
+ return lessons;
+ }
+
+ /**
+ * 查询全校学生数
+ *
+ * @return 学生总数
+ */
+ public Long studentCount(String className) {
+ if (StrUtil.isBlank(className)) {
+ return studentRepo.count();
+ } else {
+ return studentRepo.countByClassName(className);
+ }
+ }
+
+ /**
+ * 查询同学关系,根据课程
+ *
+ * @return 返回同学关系
+ */
+ public Map> findClassmatesGroupByLesson() {
+ List groupByLesson = studentRepo.findByClassmateGroupByLesson();
+ Map> result = Maps.newHashMap();
+
+ groupByLesson.forEach(classmateInfoGroupByLesson -> result.put(classmateInfoGroupByLesson.getLessonName(), classmateInfoGroupByLesson
+ .getStudents()));
+
+ return result;
+ }
+}
diff --git a/spring-boot-demo-neo4j/src/main/resources/application.yml b/spring-boot-demo-neo4j/src/main/resources/application.yml
index e69de29..22fce4e 100644
--- a/spring-boot-demo-neo4j/src/main/resources/application.yml
+++ b/spring-boot-demo-neo4j/src/main/resources/application.yml
@@ -0,0 +1,7 @@
+spring:
+ data:
+ neo4j:
+ uri: bolt://localhost
+ username: neo4j
+ password: admin
+ open-in-view: false
\ No newline at end of file
diff --git a/spring-boot-demo-neo4j/src/test/java/com/xkcoding/neo4j/Neo4jTest.java b/spring-boot-demo-neo4j/src/test/java/com/xkcoding/neo4j/Neo4jTest.java
new file mode 100644
index 0000000..da2af0d
--- /dev/null
+++ b/spring-boot-demo-neo4j/src/test/java/com/xkcoding/neo4j/Neo4jTest.java
@@ -0,0 +1,82 @@
+package com.xkcoding.neo4j;
+
+import cn.hutool.json.JSONUtil;
+import com.xkcoding.neo4j.model.Lesson;
+import com.xkcoding.neo4j.model.Student;
+import com.xkcoding.neo4j.service.NeoService;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ *
+ * 测试Neo4j
+ *
+ *
+ * @package: com.xkcoding.neo4j
+ * @description: 测试Neo4j
+ * @author: yangkai.shen
+ * @date: Created in 2018-12-24 15:17
+ * @copyright: Copyright (c) 2018
+ * @version: V1.0
+ * @modified: yangkai.shen
+ */
+@Slf4j
+public class Neo4jTest extends SpringBootDemoNeo4jApplicationTests {
+ @Autowired
+ private NeoService neoService;
+
+ /**
+ * 测试保存
+ */
+ @Test
+ public void testSave() {
+ neoService.initData();
+ }
+
+ /**
+ * 测试删除
+ */
+ @Test
+ public void testDelete() {
+ neoService.delete();
+ }
+
+ /**
+ * 测试查询 鸣人 学了哪些课程
+ */
+ @Test
+ public void testFindLessonsByStudent() {
+ // 深度为1,则课程的任教老师的属性为null
+ // 深度为2,则会把课程的任教老师的属性赋值
+ List lessons = neoService.findLessonsFromStudent("漩涡鸣人", 2);
+
+ lessons.forEach(lesson -> log.info("【lesson】= {}", JSONUtil.toJsonStr(lesson)));
+ }
+
+ /**
+ * 测试查询班级人数
+ */
+ @Test
+ public void testCountStudent() {
+ Long all = neoService.studentCount(null);
+ log.info("【全校人数】= {}", all);
+ Long seven = neoService.studentCount("第七班");
+ log.info("【第七班人数】= {}", seven);
+ }
+
+ /**
+ * 测试根据课程查询同学关系
+ */
+ @Test
+ public void testFindClassmates() {
+ Map> classmates = neoService.findClassmatesGroupByLesson();
+ classmates.forEach((k, v) -> log.info("因为一起上了【{}】这门课,成为同学关系的有:{}", k, JSONUtil.toJsonStr(v.stream()
+ .map(Student::getName)
+ .collect(Collectors.toList()))));
+ }
+}