SpringBoot整合Neo4j的简单demo

编程入门 行业动态 更新时间:2024-10-27 00:30:58

SpringBoot整合Neo4j的<a href=https://www.elefans.com/category/jswz/34/1770983.html style=简单demo"/>

SpringBoot整合Neo4j的简单demo

现在工作中开始使用Neo4j,但对照网络上的教程,导入starter后,没有@NodeEntity这个注释,所以参考官方文档,开发了一个简单demo
官方文档

简单DEMO

  1. 导入starter
	<!-- neo4j --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-neo4j</artifactId></dependency>
  1. 创建节点实体和Repository
@Node("Movie")
public class MovieEntity {@Id@GeneratedValueprivate Long id;private final String title;@Property("tagline")private final String description;@Relationship(type = "ACTED_IN", direction = Direction.INCOMING)private List<ActorEntity> actors;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;}}public MovieEntity addActor(ActorEntity actor) {if (this.actors == null) {this.actors = new ArrayList<>();}this.actors.add(actor);return this;}// getter// ...
}
@Repository
public interface MovieRepository extends Neo4jRepository<MovieEntity, Long> {@Query("MATCH (m:Movie) where m.title=$title RETURN m")List<MovieEntity> findByTitle(@Param("title") String title);
}
  1. 添加测试
    @Testpublic void testAdd() {MovieEntity entity = new MovieEntity("让子弹飞", "民国故事");entity.addActor(new ActorEntity("姜文", "中国")).addActor(new ActorEntity("周润发", "中国"));movieRepository.save(entity);}

添加自定义的RelationShip

参考relationShipProperties注释
上面的简单demo中,@Relationship声明的list中,ActorEntity类使用的是@Node注释,所以在保存时Actor被作为节点保存,而现在将类使用@RelationshipProperties声明即可
但是要注意,使用@RelationshipProperties声明的类必须有一个@TargetNode作为目标节点

// movieEntity代码
public class MovieEntity {@Id@GeneratedValueprivate Long id;private final String title;@Property("tagline")private final String description;@Relationship(value = "ACTED_IN", direction = Relationship.Direction.INCOMING)private List<RoleRelationShip> roles;
}// RoleRelationShip类代码
@RelationshipProperties
public class RoleRelationShip {@Id@GeneratedValueprivate Long id;private final String name;@TargetNodeprivate final PersonEntity person;
}// PersonEntity类与movie类相似// 测试代码@Testpublic void testAdd() {MovieEntity movie = new MovieEntity("肖申克的救赎", "自我救赎,重获自由!");movie.addRole(new RoleRelationShip("安迪·杜佛兰", new PersonEntity("Tim Robbins", "美国"))).addRole(new RoleRelationShip("瑞德", new PersonEntity("Morgan Freeman", "美国")));movieRepository.save(movie);}


可以看到relation也添加了需要的属性

自定义的Query

@Query的value可以使用SpEL,只需要使用:#{ 和 } 包装即可
使用MovieEntity更新对象

@Query("MATCH (m:Movie) where id(m)=:#{#query.id} set m.tagline=:#{#query.description} RETURN m")
MovieEntity updateById(@Param("query") MovieEntity entity);

除了@Query外的其他定制查询

主要对照文档的11.12. Is @Query the only way to use custom queries?

  1. 创建一个接口
    接口实现Neo4jRepository和CypherdslConditionExecutor接口
@Repository
public interface QueryDSLPersonRepository extends Neo4jRepository<PersonEntity, Long>, CypherdslConditionExecutor<PersonEntity> {
}
  1. 简单的查询
Node person = Cypher.node("Person").named("n");// [1]
Property name = person.property("name");
Property nation = person.property("nation");
Collection<PersonEntity> collection = queryDSLPersonRepository.findAll(name.eq(Cypher.anonParameter("Morgan Freeman")).or(nation.eq(Cypher.parameter("someName", "America"))),// [2]nation.descending()
);
for (PersonEntity personEntity : collection) {System.out.println(personEntity);
}

几点注意:
3. [1]处声明一个节点,named()方法的介绍是 Creates a copy of this node with a new symbolic name.,但我不太理解,为什么在(n:Person)内没有被修改名称,所以我只能使用"n"
4. [2]处就是查询的条件,Cypher.parameter(“someName”, “America”)和Cypher.anonParameter(“Morgan Freeman”),目前来看效果是一样的,只不过Cypher.parameter("someName", "America")就是参数使用$someName, 而不是默认的占位符

第二种定制查询

简单的基于关系的查询

@Repository
public interface PersonStatementRepository extends Neo4jRepository<PersonEntity, Long>, CypherdslStatementExecutor<PersonEntity> {
}

查询的测试代码

Node p = Cypher.node("Person").named("p");
Node m = Cypher.node("Movie").named("m");
Relationship r = p.relationshipTo(m, "ACTED_IN");// 查询参演了电影标题是"黑水"的演员
ResultStatement build = Cypher.match(r).where(m.property("title").isEqualTo(Cypher.anonParameter("黑水"))).returning(Functions.collect(p)).build();
Collection<PersonEntity> all = personStatementRepository.findAll(build);
for (PersonEntity personEntity : all) {System.out.println(personEntity);
}
System.out.println("break;");
// 查询名称以"Freeman"结尾的演员,并且以"福克斯"这个名称参演得电影
build = Cypher.match(p, r, m).where(p.property("name").endsWith(Cypher.parameter("lastName", "Freeman")).and(r.property("name").isEqualTo(Cypher.anonParameter("福克斯")))).returning(
//                Functions.collect(p),
//                Functions.collect(r),Functions.collect(m)).build();
Collection<MovieEntity> all1 = movieStatementRepository.findAll(build);
for (MovieEntity movie : all1) {System.out.println(movie);
}

控制台输出:

PersonEntity{id=5, name='Anne Hathaway', from='美国'}
PersonEntity{id=1, name='Tim Robbins', from='美国'}
break;
MovieEntity{id=6, title='蝙蝠侠:黑暗骑士', description='广受好评的超级英雄电影', roles=[]}
MovieEntity{id=9, title='蝙蝠侠:黑暗骑士崛起', description='又一部广受好评的超级英雄电影', roles=[]}

目前的几个问题
1. Cypher.match(p, r, m)的入参到底是什么?第一个statement只传入了relationship,但可以查出Person
2. 如何获得一个关联的列表?第二个查询怎么样把其关联的roles查询出来
3. returning()的用法,目前只发现一种用法,这个也行可以解决2的问题
这一种查询的复杂用法
参考这种方法,可以自定义到一些较为复杂的查询,例如下面的:查询和名称以"Freeman"结尾的演员共同演出过的演员

@Test
public void testHyperCustomerQuery() {Node p = Cypher.node("Person").named("p");Node m = Cypher.node("Movie").named("m");Node p2 = Cypher.node("Person").named("p2");Relationship r1 = p.relationshipTo(m, "ACTED_IN");Relationship r2 = p2.relationshipTo(m, "ACTED_IN");ResultStatement build = Cypher.match(r1, r2).where(p.property("name").endsWith(Cypher.parameter("lastName", "Freeman"))).returning(Functions.collect(p2)).build();Collection<PersonEntity> list = personStatementRepository.findAll(build);for (PersonEntity personEntity : list) {System.out.println(personEntity);}
}

更多推荐

SpringBoot整合Neo4j的简单demo

本文发布于:2024-02-27 12:09:29,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1706459.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:简单   SpringBoot   Neo4j   demo

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!