Docker安装
docker run -d \
--name neo4j \
-p 7474:7474 \
-p 7687:7687 \
-e NEO4J_AUTH=neo4j/hello-agents-password \
neo4j:5
SpringBoot
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
@Configuration
public class Neo4jConfig {
@Bean
public PlatformTransactionManager transactionManager(Driver driver) {
return new Neo4jTransactionManager(driver);
}
}
@Data
@Node("Actor")
public class ActorEntity {
@Id
@GeneratedValue
private Long id;
private final String name;
@Relationship(type = "演过")
private List<MovieEntity> movies = new ArrayList<>();
public ActorEntity(String name) {
this.name = name;
}
}
@Repository
public interface ActorRepository extends Neo4jRepository<ActorEntity, Long> {
ActorEntity findOneByName(String name);
@Query("MATCH (n) DETACH DELETE n")
void deleteAllData();
@Query("""
MATCH (a:Actor {name: $actorName})
MATCH (m:Movie {title: $movieTitle})
MERGE (a)-[:写过]->(m)
""")
void createActedInRelation(String actorName, String movieTitle);
}
@Data
@Node("Movie")
public class MovieEntity {
@Id
@GeneratedValue
private Long id;
private final String title;
@Property("tagline")
private final String description;
@Relationship(type = "包含", direction = Relationship.Direction.OUTGOING)
private List<ActorEntity> actors = new ArrayList<>();
public MovieEntity(String title, String description) {
this.id = null;
this.title = title;
this.description = description;
}
public MovieEntity withId(Long id) {
if (this.id.equals(id)) {
return this;
} else {
MovieEntity newObject = new MovieEntity(this.title, this.description);
newObject.id = id;
return newObject;
}
}
}
@Repository
public interface MovieRepository extends Neo4jRepository<MovieEntity, Long> {
MovieEntity findOneByTitle(String title);
@Query("""
MATCH (m:Movie {title: $title})
OPTIONAL MATCH (m)<-[:ACTED_IN]-(a:Actor)
RETURN m, collect(a) as actors
""")
MovieEntity loadMovieWithActors(String title);
}
package cn.lx.springai.neo4j;
import cn.lx.springai.SpringAiApplication;
import org.neo4j.cypherdsl.core.renderer.Configuration;
import org.neo4j.cypherdsl.core.renderer.Dialect;
import org.springframework.ai.vectorstore.qdrant.QdrantVectorStore;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.data.neo4j.core.schema.GeneratedValue;
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.Node;
import org.springframework.data.neo4j.core.schema.Property;
import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;
import java.util.List;
/**
* spring-ai
* 描述:
*
* @author liuxin
* 日期: 2025-12-09 15:51
**/
public class Neo4jTest {
static Configuration cypherDslConfiguration() {
return Configuration.newConfig()
.withDialect(Dialect.NEO4J_4).build();
}
/**
* 先创建实体
* 然后创建关系
*/
public static void test2(ActorRepository actorRepository, MovieRepository movieRepository, ConfigurableApplicationContext run) {
actorRepository.deleteAllData();
ActorEntity actor4 = new ActorEntity("吴承恩");
ActorEntity actor5 = new ActorEntity("曹雪芹");
MovieEntity movie5 = new MovieEntity("三国演义", "三分天下");
MovieEntity movie6 = new MovieEntity("红楼梦", "一群女人");
actorRepository.saveAll(List.of(actor5, actor4));
movieRepository.saveAll(List.of(movie5, movie6));
actorRepository.createActedInRelation("吴承恩", "三国演义");
}
/**
* 直接创建实体和关系
*/
public static void insert(ActorRepository actorRepository, MovieRepository movieRepository, ConfigurableApplicationContext run) {
actorRepository.deleteAllData();
// 创建电影
MovieEntity movie1 = new MovieEntity("大话西游", "至尊宝与紫霞的爱情故事");
MovieEntity movie2 = new MovieEntity("功夫", "周星驰的经典功夫喜剧");
MovieEntity movie3 = new MovieEntity("喜剧之王", "尴尬而搞笑的演艺人生");
// 创建演员
ActorEntity actor1 = new ActorEntity("周星驰");
ActorEntity actor2 = new ActorEntity("吴孟达");
ActorEntity actor3 = new ActorEntity("朱茵");
actor1.getMovies().addAll(List.of(movie1, movie2, movie3));
actor2.getMovies().addAll(List.of(movie1, movie2));
actor3.getMovies().add(movie1);
// 保存演员(关系会自动保存)
actorRepository.saveAll(List.of(actor1, actor2, actor3));
}
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(SpringAiApplication.class, args);
run.getBeanFactory().registerResolvableDependency(Configuration.class, cypherDslConfiguration());
Neo4jTransactionManager neo4jTransactionManager1 = run.getBean(Neo4jTransactionManager.class);
System.out.println(neo4jTransactionManager1);
MovieRepository movieRepository = run.getBean(MovieRepository.class);
ActorRepository actorRepository = run.getBean(ActorRepository.class);
test2(actorRepository, movieRepository, run);
}
}
控制台
http://localhost:7474/browser/
查询语句: MATCH(a:Actor)-[b:演过]-(c:Movie) RETURN a,b,c
查询所有: MATCH(n) return n
想法或问题?在 GitHub Issue 下方参与讨论
去评论