Springboot+Neo4j节点与关系的操作(三) - 知乎

前两篇文章Springboot+Neo4j 初级框架搭建(一)Springboot+Neo4j 初级增删改查(二)我们介绍了Springboot集成Neo4j,以及Neo4j单节点的操作。本篇文章我们就来写写节点与节点中关系的操作!!!话不多说直接开干。在上篇文章中,我们以公司为例子做了演示,本篇文章我们还是以公司和产品为示例演示。在生活中公司和产品有很多种关系,比如苹果是一个公司,iPhone12是一个产品,苹果和iPhone12就是一个生产的关系。我们就以这样一个简单的例子来做一个增删改查的操作

我可能又要偷懒了。首先我们在model层创建两个类,一个产品类,一个生产关系类,公司类就不创建了,上篇文章已经有了。

@NodeEntity(label = "ProductEntry")
@Data
public class ProductEntryNode {

    @Id
    private String productEntryId;

    /**
     * 模板id
     */
    private String templateId;

    /**
     * 词条名称
     */
    private String name;

    /**
     * 词条类型  1:产品种类 2:产品类型 3:产品单元
     */
    private String type;
    /**
     * 别名
     */
    private String aliasName;

    /**
     * 简介
     */
    private String introduction;
}

创建关系类@RelationshipEntity(type = "Production")表示关系类型;type = "Production"表示是什么关系,例如生产关系,后续查询会用到;@StartNode 表示开始节点;@EndNode 表示结束节点;其他的对象都是关系的属性,比如生产了多少件等。指定了开始节点和结束节点关系就有了方向,表示公司生产产品。这里的结束节点也可以和开始节点是同一个类,比如公司-公司之间是供给关系,那么这里的@EndNode就是CompanyEntryNode,这个容易理解吧

/**
 * @Author Created by YangMeng on 2021/3/4 14:09
 * 公司->生产 产品关系
 * 指定关系名称为Production
 */
@Data
@RelationshipEntity(type = "Production")
public class ProductionRelationship {

    @Id
    private String uuid;
    @StartNode
    private CompanyEntryNode startNode;

    @EndNode
    private ProductEntryNode endNode;

    /**
     * 收入占比
     */
    private String incomeProportion;

    /**
     * 毛利率
     */
    private String productGross;

    /**
     * 产品单价
     */
    private String productPrice;

    /**
     * 产能
     */
    private String capacity;

    /**
     * 产能利用率
     */
    private String capacityRatio;

    /**
     * 产能占比
     */
    private String capacityProportion;

}

分别定义产品和生产关系的dao层结构

@Repository
public interface ProductEntryRepository extends Neo4jRepository<ProductEntryNode, String> {
}
@Repository
public interface ProductionRelationshipRepository extends Neo4jRepository<ProductionRelationship, String> {
   /**
     * 根据产品获取供应商
     * @param productEntryId
     * @return
     */
    @Query("match (c:CompanyEntry)-[:Production]->(p:ProductEntry) where p.productEntryId={productEntryId} return  c.companyEntryId as companyEntryId,c.name as companyName")
    List<DicDto> getCompanyByProductId(String productEntryId);
}

在service层我们定义增删改查操作,单节点产品的我们就不做演示了。我们现在只定义生成关系的操作,在关系里我们实现定义两个接口,第一个addProductionRelationship是把公司和产品创建关系连接起来,第二个getCompanyByProductId是根据产品id查询他的供应商,也就是谁生产了它

/**
 * @Author Created by YangMeng on 2021/3/4 15:29
 */
public interface ProductionRelationshipService {

    /**
     * 添加公司产品 关系
     *
     * @param startNode
     * @param toNode
     * @return
     */
    ProductionRelationship addProductionRelationship(CompanyEntryNode startNode, ProductEntryNode toNode);

    /**
     * 添加公司产品 关系
     *
     * @param startNodeId
     * @param toNodeId
     * @return
     */
    ProductionRelationship addProductionRelationship(String startNodeId, String toNodeId);

    /**
     * 获取产品的供应商公司
     *
     * @param productEntryId
     * @return
     */
    List<DicDto> getCompanyByProductId(String productEntryId);

接着实现接口

@Service
public class ProductionRelationshipServiceImpl implements ProductionRelationshipService {

    @Autowired
    private ProductionRelationshipRepository productionRelationshipRepository;

    @Autowired
    private CompanyEntryRepository companyEntryRepository;

    @Autowired
    private ProductEntryRepository productEntryRepository;

    /**
     * 添加公司产品 关系
     *
     * @param startNode
     * @param toNode
     * @return
     */
    @Override
    public ProductionRelationship addProductionRelationship(CompanyEntryNode startNode, ProductEntryNode toNode) {
        ProductionRelationship productionRelationship = new ProductionRelationship();
        productionRelationship.setStartNode(startNode);
        productionRelationship.setEndNode(toNode);
        //添加属性
        productionRelationship.setUuid(UuidUtils.generate());
        ProductionRelationship save = productionRelationshipRepository.save(productionRelationship);
        return save;
    }

    /**
     * 添加公司产品 关系
     *
     * @param startNodeId
     * @param toNodeId
     * @return
     */
    @Override
    public ProductionRelationship addProductionRelationship(String startNodeId, String toNodeId) {
        Optional<CompanyEntryNode> byId = companyEntryRepository.findById(startNodeId);
        Optional<ProductEntryNode> byId1 = productEntryRepository.findById(toNodeId);
        if (byId.isPresent() && byId1.isPresent()) {
            return addProductionRelationship(byId.get(), byId1.get());
        }
        return new ProductionRelationship();
    }

    /**
     * 获取产品的供应商公司
     *
     * @param productEntryId
     * @return
     */
    @Override
    public List<DicDto> getCompanyByProductId(String productEntryId) {
        return productionRelationshipRepository.getCompanyByProductId(productEntryId);
    }
}

创建controller调用

@RestController
@RequestMapping(value = "productionRelationship")
@Slf4j
public class ProductionRelationshipController {

    @Autowired
    private ProductionRelationshipService productionRelationshipService;

    /**
     * 关联公司产品 关系
     *
     * @param startId
     * @param endId
     * @return
     */
    @GetMapping(value = "addRelationship")
    public WebResInfo addRelationship(String startId, String endId) {
        log.info("addRelationship->startId:{},endId:{}", startId, endId);
        WebResInfo webResInfo = new WebResInfo();
        try {
            webResInfo.setCode(WebResCode.Successful);
            ProductionRelationship productionRelationship = productionRelationshipService.addProductionRelationship(startId, endId);
            webResInfo.setData(productionRelationship);

        } catch (Exception e) {
            log.error("addRelationship error:{}", e);
            webResInfo.setCode(WebResCode.Server_Bug_Exception);
            webResInfo.setMessage(e.getMessage());
        }
        return webResInfo;
    }

    /**
     * 根据产品获取供应商信息
     *
     * @param productEntryId
     * @return
     */
    @GetMapping(value = "getCompanyByProductId")
    public WebResInfo getCompanyByProductId(String productEntryId) {
        log.info("getCompanyByProductId->productEntryId:{}", productEntryId);
        WebResInfo webResInfo = new WebResInfo();
        try {
            webResInfo.setCode(WebResCode.Successful);
            List<DicDto> companyByProductId = productionRelationshipService.getCompanyByProductId(productEntryId);
            webResInfo.setData(companyByProductId);
        } catch (Exception e) {
            log.error("getCompanyByProductId error:{}", e);
            webResInfo.setCode(WebResCode.Server_Bug_Exception);
            webResInfo.setMessage(e.getMessage());
        }
        return webResInfo;
    }

我们新增一个公司“阿里巴巴”companyEntryId为2,在新增一个产品“宝马X5”productEntryId为6,然后我们创建他们两个的关系用postman调用

这样一个关系就创建好了,然后看看我们的数据库已经创建好了关系

基于以上关系的创建,现在我们查找生产iPhone的公司有哪些

 @Query("match (c:CompanyEntry)-[:Production]->(p:ProductEntry) where p.productEntryId={productEntryId} return  c.companyEntryId as companyEntryId,c.name as companyName")
    List<DicDto> getCompanyByProductId(String productEntryId);

这里就是查询产品id为{productEntryId}的对应的公司,并且指定了关系是Production,然后就可以查出来苹果公司了。具体请求大家试试就好了

本篇主要介绍关系类型,相信大家有了一定的了解,其实neo4j里最主要还是语义化查询,有了关系我们就可以进行这样一系列查询操作,比如我搜索“iPhone12的生产商是谁”可以查询产品节点是iPhone,对应关系是生产,然后就出来了苹果公司了。这只是其中一小部分,后续还有很多。
彩蛋

下篇文章我们来讲讲Springboot同时绑定neo4j和mysql两个数据源。

有问题大家回复我。

关注下方公众号,了解更多最新内容!!!


原网址: 访问
创建于: 2022-01-05 14:55:55
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论