SpringBoot + docker + neo4j
下拉镜像
docker pull neo4j
启动镜像
docker run -d -p 7473:7473 -p 7687:7687 -p 7474:7474 neo4j
打开浏览器:http://192.168.31.146:7474/browser/
用户名/密码初始值为:neo4j
首次登陆需要修改密码
登陆后界面
新建springboot项目,添加pom引用

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-neo4j</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/com.voodoodyne.jackson.jsog/jackson-jsog --> <dependency> <groupId>com.voodoodyne.jackson.jsog</groupId> <artifactId>jackson-jsog</artifactId> <version>1.1.1</version> </dependency>
添加Actor类

package org.mythsky.neo4jdemo; import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.voodoodyne.jackson.jsog.JSOGGenerator; import org.neo4j.ogm.annotation.GraphId; import org.neo4j.ogm.annotation.NodeEntity; @JsonIdentityInfo(generator = JSOGGenerator.class) @NodeEntity public class Actor { @GraphId Long id; private String name; private int born; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getBorn() { return born; } public void setBorn(int born) { this.born = born; } }
添加Movie类

package org.mythsky.neo4jdemo; import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.voodoodyne.jackson.jsog.JSOGGenerator; import org.neo4j.ogm.annotation.GraphId; import org.neo4j.ogm.annotation.NodeEntity; import org.neo4j.ogm.annotation.Relationship; import java.util.ArrayList; import java.util.List; @JsonIdentityInfo(generator = JSOGGenerator.class) @NodeEntity public class Movie { @GraphId Long id; String title; String year; String tagline; @Relationship(type = "ACTS_IN",direction =Relationship.INCOMING) List<Role> roles = new ArrayList<>(); public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getYear() { return year; } public void setYear(String year) { this.year = year; } public String getTagline() { return tagline; } public void setTagline(String tagline) { this.tagline = tagline; } public List<Role> getRoles() { return roles; } public void setRoles(List<Role> roles) { this.roles = roles; } public Movie() { } public Role addRole(Actor actor, String name){ Role role=new Role(name,actor,this); this.roles.add(role); return role; } }
添加Role类

package org.mythsky.neo4jdemo; import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.voodoodyne.jackson.jsog.JSOGGenerator; import org.neo4j.ogm.annotation.EndNode; import org.neo4j.ogm.annotation.GraphId; import org.neo4j.ogm.annotation.RelationshipEntity; import org.neo4j.ogm.annotation.StartNode; @JsonIdentityInfo(generator = JSOGGenerator.class) @RelationshipEntity(type = "ACTS_IN") public class Role { @GraphId Long id; String role; @StartNode Actor actor; @EndNode Movie movie; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getRole() { return role; } public void setRole(String role) { this.role = role; } public Actor getActor() { return actor; } public void setActor(Actor actor) { this.actor = actor; } public Movie getMovie() { return movie; } public void setMovie(Movie movie) { this.movie = movie; } public Role(String role, Actor actor, Movie movie) { this.role = role; this.actor = actor; this.movie = movie; } public Role() { } }
添加查询接口MovieRepository

package org.mythsky.neo4jdemo; import org.springframework.data.neo4j.repository.GraphRepository; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @Repository public interface MovieRepository extends GraphRepository<Movie> { Movie findByTitle(@Param("title") String title); }
添加配置类

package org.mythsky.neo4jdemo; import org.neo4j.ogm.session.SessionFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; import org.springframework.data.neo4j.transaction.Neo4jTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @EnableTransactionManagement @EnableNeo4jRepositories public class Neo4jConfig { @Bean public SessionFactory sessionFactory() { return new SessionFactory("org.mythsky.neo4jdemo"); } @Bean public Neo4jTransactionManager transactionManager() { return new Neo4jTransactionManager(sessionFactory()); } }
添加配置文件ogm.properties

compiler=org.neo4j.ogm.compiler.MultiStatementCypherCompiler driver=org.neo4j.ogm.drivers.http.driver.HttpDriver URI=http://192.168.31.146:7474 username = neo4j password = your own password
单元测试

package org.mythsky.neo4jdemo; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @ContextConfiguration(classes = {Neo4jConfig.class}) @SpringBootTest public class Neo4jDemoApplicationTests { private static Logger logger= LoggerFactory.getLogger(Neo4jDemoApplicationTests.class); @Autowired MovieRepository movieRepository; @Before public void initData(){ movieRepository.deleteAll(); Movie matrix1=new Movie(); matrix1.setTitle("The Matrix"); matrix1.setYear("1999-03-31"); Movie matrix2=new Movie(); matrix2.setTitle("The Matrix Reloaded"); matrix2.setYear("2003-05-07"); Movie matrix3=new Movie(); matrix3.setTitle("The Matrix Revolutions"); matrix3.setYear("2003-10-27"); Actor keanu=new Actor(); keanu.setName("Keanu Reeves"); Actor laurence=new Actor(); laurence.setName("Laurence Fishburne"); Actor carrieanne=new Actor(); carrieanne.setName("Carrie-Anne Moss"); matrix1.addRole(keanu,"Neo"); matrix1.addRole(laurence,"Morpheus"); matrix1.addRole(carrieanne,"Trinity"); movieRepository.save(matrix1); Assert.assertNotNull(matrix1.getId()); matrix2.addRole(keanu,"Neo"); matrix2.addRole(laurence,"Morpheus"); matrix2.addRole(carrieanne,"Trinity"); movieRepository.save(matrix2); Assert.assertNotNull(matrix2.getId()); matrix3.addRole(keanu,"Neo"); matrix3.addRole(laurence,"Morpheus"); matrix3.addRole(carrieanne,"Trinity"); movieRepository.save(matrix3); Assert.assertNotNull(matrix3.getId()); } @Test public void get() { Movie movie=movieRepository.findByTitle("The Matrix"); Assert.assertNotNull(movie); logger.info("===movie===movie:{},{}",movie.getTitle(),movie.getYear()); for(Role role:movie.getRoles()){ logger.info("=====actor:{},role:{}",role.getActor().getName(),role.getRole()); } } }
运行测试
在浏览器查看数据
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!