基于Neo4j实现数据血缘管理

导读:本篇文章讲解 基于Neo4j实现数据血缘管理,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

1、Maven依赖

        <!--neo4j-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-neo4j</artifactId>
        </dependency>
        <dependency>
            <!-- 服务器开发需要的jar包 -->
            <groupId>org.neo4j.driver</groupId>
            <artifactId>neo4j-java-driver</artifactId>
            <version>1.7.2</version>
        </dependency>
        <dependency>
            <!-- 嵌入式开发需要的jar包 -->
            <groupId>org.neo4j</groupId>
            <artifactId>neo4j</artifactId>
            <version>3.3.4</version>
        </dependency>

2、yml配置

spring:  
  data:
    neo4j:
      uri: bolt://localhost:7687  #本地单机版neo4j
      username: neo4j
      password: neo4jj

3、配置类

import org.aspectj.lang.annotation.Aspect;
import org.neo4j.ogm.session.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Primary;
import org.springframework.data.neo4j.transaction.Neo4jTransactionManager;
import org.springframework.data.transaction.ChainedTransactionManager;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@Aspect
@Configuration
@DependsOn("sessionFactory")
@EnableTransactionManagement
public class TransactionAspect {

    ThreadLocal<TransactionStatus> transactionStatusThreadLocal = new ThreadLocal<>();

    /**
     * 定义mysql事务管理器,必须有transactionManager作为默认事务管理器
     *
     * @param dataSource
     * @return
     */
    @Bean("transactionManager")
    @Primary
    public DataSourceTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    /**
     * 定义neo4j事务管理器
     *
     * @param sessionFactory
     * @return
     */
    @Bean("neo4jTransactionManager")
    public Neo4jTransactionManager neo4jTransactionManager(SessionFactory sessionFactory) {
        return new Neo4jTransactionManager(sessionFactory);
    }

    @Autowired
    @Bean(name = "multiTransactionManager")
    public PlatformTransactionManager multiTransactionManager(
            Neo4jTransactionManager neo4jTransactionManager,
            DataSourceTransactionManager mysqlTransactionManager) {
        return new ChainedTransactionManager(
                neo4jTransactionManager, mysqlTransactionManager);
    }

}
import org.neo4j.ogm.session.SessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.transaction.Neo4jTransactionManager;

@Configuration
@EnableNeo4jRepositories(basePackages = "com.grg.data.meta.repository")
public class Neo4jConfig {

    @Bean("neo4jTransaction")
    public Neo4jTransactionManager neo4jTransactionManager(SessionFactory sessionFactory) {
        return new Neo4jTransactionManager(sessionFactory);
    }
}

4、节点类和关系类

import lombok.Builder;
import lombok.Data;
import org.neo4j.ogm.annotation.GeneratedValue;
import org.neo4j.ogm.annotation.Id;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Property;

@Builder
@Data
@NodeEntity(label = "TABLE")
public class TableNode {

    @Id
    @GeneratedValue
    private Long id;

    @Property(name = "pid")
    private Long pid;

    @Property(name = "cnName")
    private String cnName;

    @Property(name = "name")
    private String name;

    @Property(name = "dbName")
    private String dbName;

    @Property(name = "dbCnName")
    private String dbCnName;

    @Property(name = "type")
    private String type;
}
import lombok.Data;
import org.neo4j.ogm.annotation.GeneratedValue;
import org.neo4j.ogm.annotation.Id;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Property;

@Data
@NodeEntity(label = "COLUMN")
public class ColumnNode {

    @Id
    @GeneratedValue
    private Long id;

    @Property(name = "pid")
    private Long pid;

    @Property(name = "name")
    private String name;

    @Property(name = "cnName")
    private String cnName;
    
    @Property(name = "dbName")
    private String dbName;

    @Property(name = "dbCnName")
    private String dbCnName;

    @Property(name = "tableName")
    private String tableName;

    @Property(name = "tbCnName")
    private String tbCnName;

    @Property(name = "type")
    private String type;
}
import com.grg.data.meta.entity.neo4j.node.TableNode;
import lombok.Data;
import org.neo4j.ogm.annotation.*;

@Data
@RelationshipEntity(type = "tblood")
public class TableRelation {

    @Id
    @GeneratedValue
    private Long id;

    @StartNode
    private TableNode startNode;

    @EndNode
    private TableNode endNode;
}
import com.grg.data.meta.entity.neo4j.node.ColumnNode;
import lombok.Data;
import org.neo4j.ogm.annotation.*;


@Data
@RelationshipEntity(type = "blood")
public class ColumnRelation {

    @Id
    @GeneratedValue
    private Long id;

    @StartNode
    private ColumnNode startNode;

    @EndNode
    private ColumnNode endNode;
}
import com.grg.data.meta.entity.neo4j.node.ColumnNode;
import com.grg.data.meta.entity.neo4j.node.TableNode;
import lombok.Data;
import org.neo4j.ogm.annotation.*;

@Data
@RelationshipEntity(type = "has")
public class TableColumnRelation {

    @Id
    @GeneratedValue
    private Long id;

    @StartNode
    private TableNode tableNode;

    @EndNode
    private ColumnNode columnNode;

}

5、Repository类

import com.grgbanking.metadata.entity.neo4j.node.TableNode;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.Optional;
@Repository
public interface TableNodeRepository extends Neo4jRepository<TableNode, Long> {

    @Query(value = "MATCH (start:TABLE)-[:tblood*1..20]-(end:TABLE) WHERE start.tableId={tableId} RETURN start,end")
    Iterable<TableNode> findAllByTableId(@Param("tableId") Long tableId);

    @Query(value = "MATCH (t:TABLE) WHERE t.tableId={tableId} RETURN t")
    Optional<TableNode> findByTableId(@Param("tableId") Long tableId);
}
import com.grgbanking.metadata.entity.neo4j.node.ColumnNode;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

@Repository
public interface ColumnNodeRepository extends Neo4jRepository<ColumnNode, Long> {

    @Query("MATCH (t:TABLE)-[:has*1..2]-(c:COLUMN) WHERE t.tableId={tableId} RETURN c")
    Iterable<ColumnNode> findAllByTableId(@Param("tableId") Long tableId);
}

import com.grgbanking.metadata.entity.neo4j.relation.TableRelation;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface TableRelationRepository extends Neo4jRepository<TableRelation, Long> {

    @Query("match (a:TABLE), (b:TABLE) WHERE a.tableId = {startTableId} and b.tableId = {endTableId} create UNIQUE (a)-[r:tblood]->(b) return a,b,r")
    Optional<TableRelation> matchTableRelation(@Param("startTableId") Long startTableId, @Param("endTableId") Long endTableId);

    @Query(value = "MATCH p=(a:TABLE)-[r:tblood*1..20]->(:TABLE) WHERE a.tableId={tableId} RETURN p")
    Iterable<TableRelation> findRelationByTableId(@Param("tableId") Long tableId);

    @Query("match (a:TABLE)-[r:tblood]->(b:TABLE) WHERE a.tableId = {startTableId} and b.tableId = {endTableId} return a,b,r")
    Optional<TableRelation> find2TablesRelation(@Param("startTableId") Long startTableId, @Param("endTableId") Long endTableId);
}
import com.grgbanking.metadata.entity.neo4j.relation.ColumnRelation;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface ColumnRelationRepository extends Neo4jRepository<ColumnRelation, Long> {

    @Query("MATCH (a:COLUMN), (b:COLUMN) WHERE a.columnId = {startColumnId} AND b.columnId = {endColumnId} CREATE UNIQUE (a)-[r:blood{fun:{fun}}]->(b) RETURN a,b,r")
    Optional<ColumnRelation> matchColumnRelation(@Param("startColumnId") Long startColumnId, @Param("endColumnId") Long endColumnId, @Param("fun") String fun);

    @Query("MATCH c=(a:COLUMN)-[:blood*1..20]->(b:COLUMN) WHERE a.columnId={columnId} RETURN c")
    Iterable<ColumnRelation> findAllByColumnId(@Param("columnId") Long columnId);

    @Query("MATCH (c1:COLUMN)-[r:blood]->(c2:COLUMN) WHERE c1.tableId = {startTableId} AND c2.tableId = {endTableId} RETURN c1,c2,r")
    Iterable<ColumnRelation> find2TableColumnsRelation(@Param("startTableId") Long startTableId, @Param("endTableId") Long endTableId);
}
import com.grg.data.meta.entity.neo4j.relation.TableColumnRelation;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface TableColumnRelationRepository extends Neo4jRepository<TableColumnRelation, Long> {
}

6、Serivce

import com.grgbanking.metadata.dto.*;
import com.grgbanking.metadata.entity.neo4j.node.ColumnNode;
import com.grgbanking.metadata.vo.req.TableBloodReq;
import com.grgbanking.metadata.vo.req.TableNodeReq;

import java.util.List;

public interface Neo4jService {

    void addTableColumnNodes(TableColumnsDTO tableColumnsDTO);

    void addTableRelationBatch(TableRelationDTO tableRelationDTO);

    void addColumnRelation(ColumnRelationDTO columnRelationDTO);

    void add2TableAndColumnRelation(TablesAndColumnsRelationDTO tablesAndColumnsRelationDTO);

    void addColumnNodes(List<ColumnNode> columnNodes, Long tableId);


    TableNodeRelationDTO getTableNodes(TableNodeReq tableNodeReq);

    ColumnNodeRelationDTO getColumnNodesByTableId(TableNodeReq tableNodeReq);

    TablesAndColumnsRelationDTO get2TablesColumnRelation(TableBloodReq tableBloodReq);
}
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.grgbanking.metadata.common.exception.ServerException;
import com.grgbanking.metadata.dto.*;
import com.grgbanking.metadata.entity.neo4j.node.ColumnNode;
import com.grgbanking.metadata.entity.neo4j.node.TableNode;
import com.grgbanking.metadata.entity.neo4j.relation.ColumnRelation;
import com.grgbanking.metadata.entity.neo4j.relation.TableColumnRelation;
import com.grgbanking.metadata.entity.neo4j.relation.TableRelation;
import com.grgbanking.metadata.repository.*;
import com.grgbanking.metadata.service.MetadataShowService;
import com.grgbanking.metadata.service.Neo4jService;
import com.grgbanking.metadata.utils.CollectionUtils;
import com.grgbanking.metadata.vo.req.TableBloodReq;
import com.grgbanking.metadata.vo.req.TableNodeReq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

@Slf4j
@Service
public class Neo4jServiceImpl implements Neo4jService {

    @Autowired
    private MetadataShowService metadataShowService;

    @Resource
    private TableNodeRepository tableNodeRepository;

    @Resource
    private ColumnNodeRepository columnNodeRepository;

    @Resource
    private TableRelationRepository tableRelationRepository;

    @Resource
    private ColumnRelationRepository columnRelationRepository;

    @Resource
    private TableColumnRelationRepository tableColumnRelationRepository;


    /**
     * 新增单个表节点及其字段节点并建立归属关系
     *
     * @param tableColumnsDTO
     */
    @Override
    @Transactional(value = "neo4jTransaction", rollbackFor = RuntimeException.class)
    public void addTableColumnNodes(TableColumnsDTO tableColumnsDTO) {
        try {
            // 新增表节点
            TableNode tableNode = new TableNode();
            BeanUtils.copyProperties(tableColumnsDTO, tableNode);
            tableNodeRepository.save(tableNode);

            // 新增字段节点
            List<ColumnNodeDTO> columnNodeDTOList = tableColumnsDTO.getColumnNodeDTOList();
            String json = JSON.toJSONString(columnNodeDTOList);
            List<ColumnNode> columnNodes = JSON.parseObject(json, new TypeReference<List<ColumnNode>>() {
            });
            Iterable<ColumnNode> columnNodeIterable = columnNodeRepository.saveAll(columnNodes);
            int columnCount = CollectionUtils.iterableCount(columnNodeIterable);
            if (columnNodeDTOList.size() != columnCount) {
                throw new ServerException("新增columnNode条数错误!");
            }

            // 新增表和字段关系
            List<TableColumnRelation> tableColumnRelations = new ArrayList<>();

            for (ColumnNode columnNode : columnNodes) {
                TableColumnRelation tableColumnRelation = TableColumnRelation.builder()
                        .tableNode(tableNode)
                        .columnNode(columnNode)
                        .build();
                tableColumnRelations.add(tableColumnRelation);
            }
            Iterable<TableColumnRelation> columnRelationIterable = tableColumnRelationRepository.saveAll(tableColumnRelations);
            int columnRelationCount = CollectionUtils.iterableCount(columnRelationIterable);
            if (tableColumnRelations.size() != columnRelationCount) {
                throw new ServerException("columnRelation新增数错误!");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 批量建立表节点血缘关系
     *
     * @param tableRelationDTO
     */
    @Override
    @Transactional(value = "neo4jTransaction", rollbackFor = RuntimeException.class)
    public void addTableRelationBatch(TableRelationDTO tableRelationDTO) {
        List<TableRelation> tableRelationList = new ArrayList<>();
        try {
            Set<String> tableRelationSet = tableRelationDTO.getTableRelationMapList().stream().collect(HashSet::new,
                    (cr, crm) -> {
                        cr.add(crm.getStartTableId().toString() + crm.getEndTableId().toString());
                    }, (s1, s2) -> {
                        s1.addAll(s2);
                    });
            if (tableRelationSet.size() != tableRelationDTO.getTableRelationMapList().size()) {
                throw new ServerException("tableRelationMapList里存在重复数据!");
            }

            tableRelationDTO.getTableRelationMapList().forEach(v -> {
                Optional<TableRelation> optional = tableRelationRepository.matchTableRelation(v.getStartTableId(), v.getEndTableId());
                if (Objects.nonNull(optional) && optional.isPresent() && Objects.nonNull(optional.get())) {
                    tableRelationList.add(optional.get());
                }
            });
            if (tableRelationList.size() != tableRelationDTO.getTableRelationMapList().size()) {
                throw new ServerException("建立表关系异常!");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 批量建立字段节点血缘关系
     *
     * @param columnRelationDTO
     */
    @Override
    @Transactional(value = "neo4jTransaction", rollbackFor = RuntimeException.class)
    public void addColumnRelation(ColumnRelationDTO columnRelationDTO) {
        List<ColumnRelation> columnRelationList = new ArrayList<>();
        try {
            Set<String> columnRelationSet = columnRelationDTO.getColumnRelations().stream().collect(HashSet::new,
                    (cr, crm) -> {
                        cr.add(crm.getStartColumnId().toString() + crm.getEndColumnId().toString());
                    }, (s1, s2) -> {
                        s1.addAll(s2);
                    });
            if (columnRelationSet.size() != columnRelationDTO.getColumnRelations().size()) {
                throw new ServerException("ColumnRelations里存在重复数据!");
            }
            columnRelationDTO.getColumnRelations().forEach(v -> {
                Optional<ColumnRelation> optional = columnRelationRepository.matchColumnRelation(v.getStartColumnId(), v.getEndColumnId(), v.getFun());
                if (Objects.nonNull(optional) && optional.isPresent() && Objects.nonNull(optional.get())) {
                    columnRelationList.add(optional.get());
                }
            });
            if (columnRelationList.size() != columnRelationDTO.getColumnRelations().size()) {
                throw new RuntimeException("columnRelation新增数错误!");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 批量新增两个表、字段节点及其所有血缘关系
     *
     * @param tablesAndColumnsRelationDTO
     */
    @Override
    @Transactional(value = "neo4jTransaction", rollbackFor = RuntimeException.class)
    public void add2TableAndColumnRelation(TablesAndColumnsRelationDTO tablesAndColumnsRelationDTO) {
        try {
            // 1、检查startTableNode、endTableNode是否存在,不存在则抛异常
            Optional<TableNode> startTableOptional = tableNodeRepository.findByTableId(tablesAndColumnsRelationDTO.getStartTableId());
            Optional<TableNode> endTableOptional = tableNodeRepository.findByTableId(tablesAndColumnsRelationDTO.getEndTableId());

            if (!startTableOptional.isPresent() || !endTableOptional.isPresent()) {
                throw new ServerException("表节点不存在");
            }

            // 2、建立表和表之间的血缘
            Optional<TableRelation> tableRelationOptional = tableRelationRepository.matchTableRelation(tablesAndColumnsRelationDTO.getStartTableId(), tablesAndColumnsRelationDTO.getEndTableId());
            if (Objects.isNull(tableRelationOptional) || !tableRelationOptional.isPresent()) {
                throw new RuntimeException("tableRelation建立失败!");
            }

            // 3、批量建立字段之间的血缘
            ColumnRelationDTO columnRelationDTO = new ColumnRelationDTO();
            columnRelationDTO.setColumnRelations(tablesAndColumnsRelationDTO.getColumnRelations());
            this.addColumnRelation(columnRelationDTO);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 新增column node并和table node绑定
     * @param columnNodes
     * @param tableId
     */
    @Override
    @Transactional(value = "neo4jTransaction", rollbackFor = RuntimeException.class)
    public void addColumnNodes(List<ColumnNode> columnNodes, Long tableId) {
        try {
            Optional<TableNode> tableNodeOptional = tableNodeRepository.findByTableId(tableId);
            if (!tableNodeOptional.isPresent()) {
                log.error("tableNode不存在,tableId:{}", tableId);
                throw new ServerException("tableNode不存在!");
            }

            // 新增column node
            Iterable<ColumnNode> iterable = columnNodeRepository.saveAll(columnNodes);
            Iterator<ColumnNode> iterator = iterable.iterator();
            int columnCount = CollectionUtils.iterableCount(iterable);
            if (columnNodes.size() != columnCount) {
                throw new ServerException("新增columnNode条数错误!");
            }

            // 新增table column relation
            List<TableColumnRelation> tableColumnRelations = new ArrayList<>();
            while (iterator.hasNext()) {
                ColumnNode columnNode = iterator.next();
                TableColumnRelation tableColumnRelation = TableColumnRelation.builder()
                        .tableNode(tableNodeOptional.get())
                        .columnNode(columnNode)
                        .build();
                tableColumnRelations.add(tableColumnRelation);
            }

            Iterable<TableColumnRelation> columnRelationIterable = tableColumnRelationRepository.saveAll(tableColumnRelations);
            int columnRelationCount = CollectionUtils.iterableCount(columnRelationIterable);
            if (tableColumnRelations.size() != columnRelationCount) {
                throw new ServerException("新增tableColumnRelation条数错误!");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage());
        }
    }


    @Override
    public TableNodeRelationDTO getTableNodes(TableNodeReq tableNodeReq) {
        TableNodeRelationDTO tableNodeRelationDTO = new TableNodeRelationDTO();
        Iterable<TableNode> tableNodeIterable = tableNodeRepository.findAllByTableId(tableNodeReq.getTableId());
        Iterable<TableRelation> tableRelationIterable = tableRelationRepository.findRelationByTableId(tableNodeReq.getTableId());
        tableNodeRelationDTO.setTableNodeIterable(tableNodeIterable);
        tableNodeRelationDTO.setTableRelationIterable(tableRelationIterable);
        return tableNodeRelationDTO;
    }

    @Override
    public ColumnNodeRelationDTO getColumnNodesByTableId(TableNodeReq tableNodeReq) {
        ColumnNodeRelationDTO columnNodeRelationDTO = new ColumnNodeRelationDTO();
        Map<Long, Iterable<ColumnRelation>> columnRelationMap = new HashMap<>();

        Iterable<ColumnNode> columnNodeIterable = columnNodeRepository.findAllByTableId(tableNodeReq.getTableId());
        columnNodeRelationDTO.setColumnNodeIterable(columnNodeIterable);


        Iterator<ColumnNode> columnNodeIterator = columnNodeIterable.iterator();
        while (columnNodeIterator.hasNext()) {
            ColumnNode columnNode = columnNodeIterator.next();
            Iterable<ColumnRelation> columnRelationIterable = columnRelationRepository.findAllByColumnId(columnNode.getColumnId());
            columnRelationMap.put(columnNode.getColumnId(), columnRelationIterable);
        }
        columnNodeRelationDTO.setColumnRelationMap(columnRelationMap);

        return columnNodeRelationDTO;
    }

    @Override
    public TablesAndColumnsRelationDTO get2TablesColumnRelation(TableBloodReq tableBloodReq) {
        TablesAndColumnsRelationDTO tablesAndColumnsRelationDTO = new TablesAndColumnsRelationDTO();
        List<ColumnRelationMap> columnRelations = new ArrayList<>();

        Optional<TableRelation> tableRelationOptional = tableRelationRepository.find2TablesRelation(tableBloodReq.getStartTableId(), tableBloodReq.getEndTableId());
        if (Objects.isNull(tableRelationOptional) || !tableRelationOptional.isPresent()) {
            return null;
        }

        tablesAndColumnsRelationDTO.setStartTableId(tableRelationOptional.get().getStartNode().getTableId());
        tablesAndColumnsRelationDTO.setStartTableCode(tableRelationOptional.get().getStartNode().getTableCode());
        tablesAndColumnsRelationDTO.setEndTableId(tableRelationOptional.get().getEndNode().getTableId());
        tablesAndColumnsRelationDTO.setEndTableCode(tableRelationOptional.get().getEndNode().getTableCode());

        Iterable<ColumnRelation> columnRelationIterable = columnRelationRepository.find2TableColumnsRelation(tableBloodReq.getStartTableId(), tableBloodReq.getEndTableId());
        Iterator<ColumnRelation> columnRelationIterator = columnRelationIterable.iterator();

        while (columnRelationIterator.hasNext()) {
            ColumnRelation columnRelation = columnRelationIterator.next();
            String fun = columnRelation.getFun();
            Long startColumnId = columnRelation.getStartNode().getColumnId();
            String startColumnCode = columnRelation.getStartNode().getColumnCode();
            Long endColumnId = columnRelation.getEndNode().getColumnId();
            String endColumnCode = columnRelation.getEndNode().getColumnCode();
            columnRelations.add(ColumnRelationMap.builder()
                    .startColumnId(startColumnId).endColumnId(endColumnId).fun(fun).startColumnCode(startColumnCode).endColumnCode(endColumnCode)
                    .build());
        }

        tablesAndColumnsRelationDTO.setColumnRelations(columnRelations);
        return tablesAndColumnsRelationDTO;
    }
}

7、Controller

import com.grgbanking.metadata.consts.Constants;
import com.grgbanking.metadata.dto.*;
import com.grgbanking.metadata.entity.neo4j.node.TableNode;
import com.grgbanking.metadata.service.Neo4jService;
import com.grgbanking.metadata.vo.ResultResponse;
import com.grgbanking.metadata.vo.req.TableBloodReq;
import com.grgbanking.metadata.vo.req.TableNodeReq;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@Api(value = "/数据血缘", tags = "数据血缘", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@RestController
@RequestMapping(value = Constants.BASE_API_PATH + "/neo4j", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class Neo4jController {

    @Autowired
    private Neo4jService neo4jService;

   
    @ApiOperation(value = "新增单个表节点及其字段节点并建立归属关系", consumes = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/addTableColumnNodes", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<ResultResponse<List<TableNode>>> addTableColumnNodes(@Validated @RequestBody TableColumnsDTO tableColumnsDTO,
                                                                               HttpServletRequest request) {
        neo4jService.addTableColumnNodes(tableColumnsDTO);
        return ResponseEntity.ok(new ResultResponse().success());
    }

    @ApiOperation(value = "批量建立表节点血缘关系", consumes = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/addTableRelation", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<ResultResponse> addTableRelation(@Validated @RequestBody TableRelationDTO tableRelationDTO, HttpServletRequest request) {

        neo4jService.addTableRelationBatch(tableRelationDTO);
        return ResponseEntity.ok(new ResultResponse().success());
    }

    @ApiOperation(value = "批量建立字段节点血缘关系", consumes = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/addColumnRelation", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<ResultResponse> addColumnRelation(@Validated @RequestBody ColumnRelationDTO columnRelationDTO, HttpServletRequest request) {

        neo4jService.addColumnRelation(columnRelationDTO);
        return ResponseEntity.ok(new ResultResponse().success());
    }

    @ApiOperation(value = "批量新增两个表、字段节点及其所有血缘关系", consumes = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/add2TableAndColumnRelation", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<ResultResponse> add2TableAndColumnRelation(@Validated @RequestBody TablesAndColumnsRelationDTO tablesAndColumnsRelationDTO, HttpServletRequest request) {

        neo4jService.add2TableAndColumnRelation(tablesAndColumnsRelationDTO);
        return ResponseEntity.ok(new ResultResponse().success());
    }

    /*************************-------以下是查询接口-----------*******************************/

    @ApiOperation(value = "获取表节点及其表血缘关系", consumes = MediaType.APPLICATION_JSON_VALUE)
    @GetMapping(value = "/getTableNodes")
    public ResponseEntity<ResultResponse<TableNodeRelationDTO>> getTableNodes(@Validated TableNodeReq tableNodeReq, HttpServletRequest request) {
        TableNodeRelationDTO tableNodeRelationDTO = neo4jService.getTableNodes(tableNodeReq);
        return ResponseEntity.ok(new ResultResponse().success(tableNodeRelationDTO));
    }

    @ApiOperation(value = "获取某个表下所有字段节点", consumes = MediaType.APPLICATION_JSON_VALUE)
    @GetMapping(value = "/getColumnNodesByTableId")
    public ResponseEntity<ResultResponse<ColumnNodeRelationDTO>> getColumnNodesByTableId(@Validated TableNodeReq tableNodeReq, HttpServletRequest request) {
        ColumnNodeRelationDTO columnNodeRelationDTO = neo4jService.getColumnNodesByTableId(tableNodeReq);
        return ResponseEntity.ok(new ResultResponse().success(columnNodeRelationDTO));
    }

    @ApiOperation(value = "获取表之间的血缘关系及其字段之间的血缘关系", consumes = MediaType.APPLICATION_JSON_VALUE)
    @GetMapping(value = "/get2TablesColumnRelation")
    public ResponseEntity<ResultResponse<TablesAndColumnsRelationDTO>> get2TablesColumnRelation(@Validated TableBloodReq tableBloodReq, HttpServletRequest request) {
        TablesAndColumnsRelationDTO tablesAndColumnsRelationDTO = neo4jService.get2TablesColumnRelation(tableBloodReq);
        return ResponseEntity.ok(new ResultResponse().success(tablesAndColumnsRelationDTO));
    }
}

8 总结

本文章仅仅提供了Neo4j做数据血缘的设计,提供Restful-Api 对数据血缘的增删查改,至于数据血缘的解析,需要先在另外的模块进行处理。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/71366.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!