ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Springboot连接Neo4j,SDN 6.0+版

2021-07-20 10:02:48  阅读:472  来源: 互联网

标签:name Country 节点 6.0 Neo4j SDN country public String


Springboot连接Neo4j

本文档介绍利用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/

0 事前配置

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

项目结构:

  • controller
  • domain
    • node
    • relationship
  • repository
  • service

1 domain包

domain中为Neo4j数据库中存放的实体类,包括节点类和关系类,分别置于node包和relationship包中

1.1 node包

对应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;
}
  • @Node注解,声明这是一个节点类,primaryLabel参数为该节点的主标签;
  • @Id与@GeneratedValue注解,声明该成员是一个自动生成的id,Neo4j中的id为长整型类Long;
  • @Property注解,声明该成员是本节点的一个属性,name参数为该属性的名称;
  • @Relationship注解,声明该成员是与本节点有关的关系的列表,
    • type参数为该关系的名称;
    • direction参数为该关系的方向,离开本节点(OUTGOING,默认)或进入本节点(INCOMING)。
    • 注意:当关系一端的节点声明了此关系,另一端的节点一定不能声明同一关系,否侧会由于循环嵌套出现stackOverflow错误!

1.2 relationship包

对应Neo4j数据库中的关系。以BuildIn.java为例:

@RelationshipProperties
@Data
@Builder
public class BuildIn {
    @Id
    @GeneratedValue
    Long id;

    @TargetNode
    private Ship ship;

    private int year;
}
  • @RelationshipProperties注解,声明这是一个关系类,其中必须包含一个@Id和@GeneratedValue注解声明的id;
  • @TargetNode注解,声明该关系的另一端节点。

2 repository包

包含各个节点类与数据库的交互,每个接口均继承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)。

3 Service包

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为添加关系的方法,此处先判断该关系是否已存在,若不存在则在该类的关系列表中添加该关系,即可实现数据库中的关系添加,删除关系同理,之后覆盖对应节点。

4 controller包

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服务类即可调用对应方法。

5 运行结果与高级方法

查询所有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": "美国"
    },
    ...
]

就不再有关系输出了。

标签:name,Country,节点,6.0,Neo4j,SDN,country,public,String
来源: https://blog.csdn.net/m0_45893438/article/details/118927427

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有