赞
踩
本文档介绍利用Springboot连接Neo4j数据库实现节点、关系的增删改查。所有代码均可查看官方指导:https://docs.spring.io/spring-data/neo4j/docs/6.1.2/reference/html/#reference以及官方手册https://docs.spring.io/spring-data/neo4j/docs/6.1.2/api/
pom.xml中:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
版本为6.1.2,6+版本应该通用。
application.properties中:
# neo4j配置
spring.neo4j.uri = bolt://localhost:7687
spring.neo4j.authentication.username = usrname
spring.neo4j.authentication.password = pwd
项目结构:
domain中为Neo4j数据库中存放的实体类,包括节点类和关系类,分别置于node包和relationship包中
对应Neo4j数据库中的节点。以Country.java为例:
@Node(primaryLabel = "Country")
@Data
@Builder
public class Country {
@Id
@GeneratedValue
Long id;
@Property(name = "name")
private String name;
@Relationship(type = "buildIn", direction = Relationship.Direction.INCOMING)
private List<BuildIn> buildIn;
}
对应Neo4j数据库中的关系。以BuildIn.java为例:
@RelationshipProperties
@Data
@Builder
public class BuildIn {
@Id
@GeneratedValue
Long id;
@TargetNode
private Ship ship;
private int year;
}
包含各个节点类与数据库的交互,每个接口均继承Neo4jRepository接口。以CountryRepository为例:
@Repository
public interface CountryRepository extends Neo4jRepository<Country, Long> {
/*
按照name查询国家
*/
Country findFirstByName(String name);
}
findAll、save、delete等基础方法已默认包含,无需额外声明。
简单查询可以自动生成,复杂查询等语句需要用@Query注解写查询语句,如:
@Query(value = "match p=(s:Ship)-[]-() where s.name={0} return p")
List<PathValue> getRelationshipByName(String name);
查询某一艘船及其对应的所有关系,得到的结果为org.neo4j.driver.internal.value.PathValue的列表
Spring Data Neo4j 6+版本中不在支持将关系作为查询结果,自动映射的对象必须为有主标签的节点或节点的映射,或Neo4j的原始数据类(如Path或Node)。
service包中为系统提供的服务,涉及部分逻辑与repository接口中方法的封装,以CountryService.java为例:
@Service public class CountryService { @Autowired private CountryRepository countryRepository; @Autowired private ShipRepository shipRepository; public List<Country> getAllCountry(){ return countryRepository.findAll(); } public Country getCountryByName(String name){ return countryRepository.findFirstByName(name); } public Country addCountry(String name){ return countryRepository.save(Country.builder().name(name).build()); } public void deleteCountry(String name){ countryRepository.delete(getCountryByName(name)); } public Country addBuildInRelationship(String shipName, String countryName, int year){ Country country = countryRepository.findFirstByName(countryName); Ship ship = shipRepository.findFirstByName(shipName); for (BuildIn b : country.getBuildIn()){ if (b.getShip().getName().equals(shipName)){ return country; } } country.getBuildIn().add(BuildIn.builder().ship(ship).year(year).build()); return countryRepository.save(country); } }
自动注入repository后,封装数据库的增删改查。
其中addBuildInRelationship为添加关系的方法,此处先判断该关系是否已存在,若不存在则在该类的关系列表中添加该关系,即可实现数据库中的关系添加,删除关系同理,之后覆盖对应节点。
controller包中为springboot的控制器,以CountryController.java为例:
@RestController @RequestMapping("/country") public class CountryController { @Autowired private CountryService countryService; @GetMapping("/get_all_country") public List<Country> getAllCountry(){ return countryService.getAllCountry(); } @GetMapping("/get_country") public Country getCountry(@RequestParam("name")String name){ return countryService.getCountryByName(name); } @PostMapping("/add_country") public Country addCountry(@RequestParam("name")String name){ return countryService.addCountry(name); } @DeleteMapping("/delete_country") public void deleteCountry(@RequestParam("name")String name){ countryService.deleteCountry(name); } @PostMapping("/add_build_in_relationship") public Country addBuildInRelationship( @RequestParam("shipName")String shipName, @RequestParam("countryName")String countryName, @RequestParam("year")int year){ return countryService.addBuildInRelationship(shipName, countryName, year); } }
自动注入ControllerService服务类即可调用对应方法。
查询所有country运行结果:
[ { "name": "泛美", "buildIn": [] },{ "name": "美国", "buildIn": [ { "id": 88, "ship": { "name": "得梅因", "tier": 10 }, "year": 1941 }, ... ] }, ... ]
看到查询输出的是之前设定的Country.java类中的成员,包括所有的关系,此时可以通过projection映射对输出结果进行筛选与重组。
以CountryProjection.java接口为例:
public interface CountryProjection {
String getName();
}
设置只得到Country类中的name成员;修改CountryRepository.java中的方法,添加:
List<CountryProjection> findAllBy();
得到全部Country的映射,即只得到name,增加对应Service方法与Controller方法,运行结果:
[
{
"name": "泛美"
},
{
"name": "美国"
},
...
]
就不再有关系输出了。
2022.11.20
这个demo是挺久之前写的了,代码规范部分现在看问题挺大的,最近也没有碰过neo4j了,因此现在翻出来的这个代码说实话有点处刑的感觉,但是能用,姑且一看,代码在这。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。