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