# 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 ## pom.xml ```xml 4.0.0 spring-boot-demo-neo4j 1.0.0-SNAPSHOT jar spring-boot-demo-neo4j Demo project for Spring Boot com.xkcoding spring-boot-demo 1.0.0-SNAPSHOT UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-data-neo4j org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.projectlombok lombok true cn.hutool hutool-all com.google.guava guava spring-boot-demo-neo4j org.springframework.boot spring-boot-maven-plugin ``` ## application.yml ```yaml spring: data: neo4j: uri: bolt://localhost username: neo4j password: admin open-in-view: false ``` ## CustomIdStrategy.java ```java /** *

* 自定义主键策略 *

* * @author yangkai.shen * @date Created in 2018-12-24 14:40 */ public class CustomIdStrategy implements IdStrategy { @Override public Object generateId(Object o) { return IdUtil.fastUUID(); } } ``` ## 部分Model代码 ### Student.java ```java /** *

* 学生节点 *

* * @author yangkai.shen * @date Created in 2018-12-24 14:38 */ @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; } ``` ## 部分Repository代码 ### StudentRepository.java ```java /** *

* 学生节点Repository *

* * @author yangkai.shen * @date Created in 2018-12-24 15:05 */ 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); /** * 查询满足 (学生)-[选课关系]-(课程)-[选课关系]-(学生) 关系的 同学 * * @return 返回同学关系 */ @Query("match (s:Student)-[:R_LESSON_OF_STUDENT]->(l:Lesson)<-[:R_LESSON_OF_STUDENT]-(:Student) with l.name as lessonName,collect(distinct s) as students return lessonName,students") List findByClassmateGroupByLesson(); /** * 查询师生关系,(学生)-[班级学生关系]-(班级)-[班主任关系]-(教师) * * @return 返回师生关系 */ @Query("match (s:Student)-[:R_STUDENT_OF_CLASS]->(:Class)-[:R_BOSS_OF_CLASS]->(t:Teacher) with t.name as teacherName,collect(distinct s) as students return teacherName,students") List findTeacherStudentByClass(); /** * 查询师生关系,(学生)-[选课关系]-(课程)-[任教老师关系]-(教师) * * @return 返回师生关系 */ @Query("match ((s:Student)-[:R_LESSON_OF_STUDENT]->(:Lesson)-[:R_TEACHER_OF_LESSON]->(t:Teacher))with t.name as teacherName,collect(distinct s) as students return teacherName,students") List findTeacherStudentByLesson(); } ``` ## Neo4jTest.java ```java /** *

* 测试Neo4j *

* * @author yangkai.shen * @date Created in 2018-12-24 15:17 */ @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())))); } /** * 查询所有师生关系,包括班主任/学生,任课老师/学生 */ @Test public void testFindTeacherStudent() { Map> teacherStudent = neoService.findTeacherStudent(); teacherStudent.forEach((k, v) -> log.info("【{}】教的学生有 {}", k, JSONUtil.toJsonStr(v.stream() .map(Student::getName) .collect(Collectors.toList())))); } } ``` ## 截图 运行测试类之后,可以通过访问 http://localhost:7474 ,查看neo里所有节点和关系 ![image-20181225150513101](http://static.xkcoding.com/spring-boot-demo/neo4j/063605.jpg) ## 参考 - spring-data-neo4j 官方文档:https://docs.spring.io/spring-data/neo4j/docs/5.1.2.RELEASE/reference/html/ - neo4j 官方文档:https://neo4j.com/docs/getting-started/3.5/