2025/7/3

今天目标

  • 路线规划需求分析
  • 路线规划实现方案分析
  • Neo4j的快速入门
  • 学习Spring Data Neo4j


学之前先思考:

理解为什么使用Neo4j来实现路线规划?      图数据形式存储能更高效找到运输路线

Neo4j中Cypher基本操作有哪些?

Spring Data Neo4j如何使用?


业务二:神领核心功能-路线规划需求分析

看这个路线,一条一条找有点费劲而且代码复杂不好维护,解决方案就是路线

业务二:神领核心功能-路线规划需求分析

如果数据能够按照图形的方式存储,那么对于运输路线的计算就会更高效一些       “一图胜千言万语”

所以就用到了图数据库(Neo4j):以图的方式存储数据



先总结:

今天学了两个点 一、Cypher基本操作 二、Spring Data Neo4j的用法


一、Cypher基本操作

什么是Neo4j?

Neo4j是用Java实现的开源NoSQL图数据库。      

Neo4j能做什么?

如:网络管理、软件分析、组织和项目管理、社交项目等方面都有应用。

Neo4j怎么使用?

借助Neo4j的查询语言Cypher即可使用  (类似MySQL的SQL查询语句)


1、安装然后打开

docker run 
-d 
--restart=always 
--name neo4j 
-p 7474:7474 
-p 7687:7687 
-v neo4j:/data 
neo4j:4.4.5

# 7474是web管理工具的端口,7687是neo4j协议端口进行数据通信

打开浏览器,输入地址:http://neo4j.sl-express.com/browser/

用户名:neo4j,密码:neo4j123



2、先对Neo4j有个基本认识 ,Neo4j中采用节点、属性、关系、标签来存储数据。如下:

节点:每一条数据

属性:每条数据都有哪些属性

关系:节点和节点之间的关系(关系是人为定制的)

标签:给节点分类


3、好了基本概念也了解了,现在通过Cypher正式入门Neo4j

注意:理解能看懂语法就行,不需要能默写

详细看文档的创建、查询、更新、删除数据,重点在分页查询数据


二、Spring Data Neo4j的用法

1、搭建环境:

依赖、配置、基础代码(引导类、实体类、DTO)

2、Repository:

SDN也是遵循了Spring Data规范,同时也提供了Neo4jRepository,

该接口中提供了基本的CRUD操作,我们定义Repository需要继承该接口来实现增删改查并且不用写具体实现。

3、复杂查询

继承Neo4jRepository实现简单的查询是非常方便的,如果要实现复杂的查询就需要定义Cypher查询实现了,需要通过Neo4jClient进行查询操作






做路线规划业务的基本常识了解之后,正式开始完成功能

对于运输路线规划,总的需求有两个,一个是机构管理,一个是路线管理。


2025/7/4

路线规划(一)机构管理

机构管理

1、分析需求:

对于机构管理中基本信息的维护(比如机构地址、机构负责人,联系电话等

但是我们发现,后台系统中并没有新增机构的相关按钮操作,那么这个机构信息在哪里新增呢?

==注意:机构的基本信息都是存储到Neo4j中的==


这时候就用到权限管家

业务二:神领核心功能-路线规划需求分析

机构的管理是需要与【权限管家】系统中的【组织管理】中的数据进行同步操作的,也就是机构的新增是在权限管家里实现的,那么同步是需要通过RabbitMQ完成的,避免代码重复

拉取基础代码略


2、具体实现

业务二:神领核心功能-路线规划需求分析


机构管理主要是围绕这两个维度来写

1、MQ配置

相关MQ的配置信息在Nacos中的sl-express-transport-properties配置文件中,包含了相同的交换机

业务二:神领核心功能-路线规划需求分析

2、监听业务实现

业务二:神领核心功能-路线规划需求分析


package com.sl.transport.listener;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.sl.transport.common.constant.Constants;
import com.sl.transport.entity.node.AgencyEntity;
import com.sl.transport.entity.node.BaseEntity;
import com.sl.transport.entity.node.OLTEntity;
import com.sl.transport.entity.node.TLTEntity;
import com.sl.transport.enums.OrganTypeEnum;
import com.sl.transport.service.IService;
import com.sl.transport.utils.OrganServiceFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class AuthMQListener {
    /**
     * 监听权限管家过来的消息
     * @param msg
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = Constants.MQ.Queues.AUTH_TRANSPORT),
            exchange = @Exchange(name ="${rabbitmq.exchange}",type = ExchangeTypes.TOPIC),
            key = "#"
    ))
    public void listenAgencyMsg(String msg){

        log.info("接受到的数据:"+msg);
        //消息的格式如下     其中:operation类型列表 新增-ADD 修改-UPDATE  删除-DEL
//{"type":"ORG","operation":"ADD","content":[{"id":"977263044792942657","name":"北京转运中心","parentId":"0","managerId":null,"status":true}]}
//{"type":"ORG","operation":"ADD","content":[{"id":"977263044792954321","name":"顺义分拣中心","parentId":"977263044792942657","managerId":null,"status":true}]}
//{"type":"ORG","operation":"ADD","content":[{"id":"977263044792951234","name":"马坡营业部","parentId":"977263044792954321","managerId":null,"status":true}]}

        // 为了更好的获取json字符串中的属性值 转成json对象
        JSONObject jsonObject = JSONUtil.parseObj(msg);

        String type = jsonObject.getStr("type");
        // 判断是否为ORG
        if(!StrUtil.equals(type,"ORG")){
            return;
        }

        // 判断 一级 二级 网点
        // 获取实体的Json对象
        JSONObject entityJsonObject = (JSONObject) jsonObject.getJSONArray("content").get(0);
        String name = entityJsonObject.getStr("name");
        BaseEntity entity = null;

        IService iservice = null;
        if (name.endsWith("转运中心")) {  // 一级转运中心
            entity = new OLTEntity();
            iservice = OrganServiceFactory.getBean(OrganTypeEnum.OLT.getCode());
        }
        if (name.endsWith("分拣中心")) {  // 二级转运中心
            entity = new TLTEntity();
            iservice = OrganServiceFactory.getBean(OrganTypeEnum.TLT.getCode());
        }
        if (name.endsWith("营业部")) {  // 网点
            entity = new AgencyEntity();
            iservice = OrganServiceFactory.getBean(OrganTypeEnum.AGENCY.getCode());
        }
        entity.setParentId(entityJsonObject.getLong("parentId"));
        entity.setBid(entityJsonObject.getLong("id"));
        entity.setName(name);
        entity.setStatus(entityJsonObject.getBool("status"));

        String operation = jsonObject.getStr("operation");
        // 判断是   UPDATE DEL
        switch (operation) {
            case "ADD":{
                iservice.create(entity);
                log.info("新增操作");
                break;
            }
            case "UPDATE":{
                iservice.update(entity);
                log.info("修改操作");
                break;
            }
            case "DEL":{
                iservice.deleteByBid(entity.getBid());
                log.info("删除操作");
                break;
            } default:{
                break;
            }
        }
    }
}

赋值的时候注意!!!业务二:神领核心功能-路线规划需求分析

手动创建4个实现类

业务二:神领核心功能-路线规划需求分析

再处理完小坑就完事了

业务二:神领核心功能-路线规划需求分析


路线规划(二)线路管理