Neo4j(CQL)学习记录-04(Cypher Query Language)

5 篇文章 0 订阅
4 篇文章 0 订阅

在上一章中因为spring-data-Neo4j最新版本中一些api问题,导致生成的关系会变成节点,使用了另一种方式生成关系,但是那种方式无法正常生成关系的属性,这一篇文章将不使用官方提供的增删查改api,使用记录一下使用字符串拼接的方式来实现节点,关系的插入,下面记录一下实现工具类

不用spring-data0Neo4j的api来实现对节点的增删改查原因

  1. 因为api中继承Neo4jRepository的方法来实现,新增时,需要指定实体类,以及指定关系,无法做到动态传参;
  2. 就是因为上一章中使用官方给出的demo无法正常插入节点和关系

插入节点(插入单个属性)

import jakarta.annotation.Resource;
import org.neo4j.driver.Driver;
import org.neo4j.driver.Session;
import org.neo4j.driver.Value;
import org.neo4j.driver.Values;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
public class Neo4jUtil {
    @Resource
    private Driver driver;
    /**
     * 功能描述:创建节点
     *
     * @param label         节点名
     * @param propertyName  属性名称
     * @param propertyValue 属性值
     * @author zhongzy
     * @date 2024/05/16
     */

    public void createNode(String label, String propertyName, String propertyValue){
        try(Session session = driver.session()){
            session.run("CREATE (n:" + label + " {" + propertyName + ": $propertyValue})", parameters("propertyValue", propertyValue));
        }
    }


    private static Value parameters(Object... values) {
        return Values.parameters(values);
    }
}

插入节点(插入多个属性)

 /**
     * 功能描述:创建节点多个属性值
     *
     * @param label      标签
     * @param properties 多属性
     * @author zhongzy
     * @date 2024/05/16
     */

    public void createNode(String label, Map<String, Object> properties){
        try(Session session = driver.session()){
            StringBuilder sb = new StringBuilder("CREATE (n:" + label + " {");
            for(Map.Entry<String, Object> entry : properties.entrySet()){
                sb.append(entry.getKey()).append(": $").append(entry.getKey()).append(", ");
            }
            sb.setLength(sb.length() - 2);
            sb.append("})");
            session.run(sb.toString(), Values.value(properties));
        }
    }

指定节点添加关系(初级版本)

    /**
     * 功能描述:
     *
     * @param fromLabel         起始节点
     * @param fromProperty      起始属性
     * @param fromPropertyValue 起始属性值
     * @param toLabel           目标节点
     * @param toProperty        目标属性
     * @param toPropertyValue   目标属性值
     * @param relationshipType  关系类型
     * @author zhongzy
     * @date 2024/05/16
     */

    public void createRelationship(String fromLabel, String fromProperty, String fromPropertyValue,
                                   String toLabel, String toProperty, String toPropertyValue, String relationshipType){
        try(Session session = driver.session()){
            session.run("MATCH (a:" + fromLabel + " {" + fromProperty + ": $fromPropertyValue}) "
                            + "MATCH (b:" + toLabel + " {" + toProperty + ": $toPropertyValue}) "
                            + "CREATE (a)-[r:" + relationshipType + "]->(b)",
                    parameters("fromPropertyValue", fromPropertyValue, "toPropertyValue", toPropertyValue));
        }
    }

指定节点添加关系以及关系属性

因为上面这个方法会有问题,节点属性不一定传入,所以拼接会有问题,进行一下修改

    /**
     * 功能描述:
     *
     * @param fromLabel              起始节点
     * @param fromProperties         起始节点属性
     * @param toLabel                目标节点
     * @param toProperties           目标节点属性
     * @param relationshipType       关系类型
     * @param relationshipProperties 关系属性
     * @author zhongzy
     * @date 2024/05/16
     */

    public void createRelationship(String fromLabel, Map<String, Object> fromProperties,
                                   String toLabel, Map<String, Object> toProperties,
                                   String relationshipType, Map<String, Object> relationshipProperties) {
        try (Session session = driver.session()) {
            StringBuilder sb = new StringBuilder("MATCH (a:" + fromLabel);
            appendProperties(sb, "a", fromProperties);
            sb.append(") MATCH (b:" + toLabel);
            appendProperties(sb, "b", toProperties);
            sb.append(") CREATE (a)-[r:" + relationshipType);
            appendProperties(sb, "r", relationshipProperties);
            sb.append("]->(b)");

            Map<String, Object> parameters = new HashMap<>();
            addPropertiesToParameters(parameters, addPrefixToProperties(fromProperties, "a_"));
            addPropertiesToParameters(parameters, addPrefixToProperties(toProperties, "b_"));
            addPropertiesToParameters(parameters, addPrefixToProperties(relationshipProperties, "r_"));

            session.run(sb.toString(), parameters);
        }
    }

    private void appendProperties(StringBuilder sb, String variable, Map<String, Object> properties) {
        if (properties != null && !properties.isEmpty()) {
            sb.append(" {");
            for (Map.Entry<String, Object> entry : properties.entrySet()) {
                sb.append(entry.getKey()).append(": $").append(variable).append("_").append(entry.getKey()).append(", ");
            }
            sb.setLength(sb.length() - 2);
            sb.append("}");
        }
    }

    /**
     * 功能描述:这里占位符需要单独的标识来拼接
     *
     * @param properties 属性
     * @param prefix     前缀
     * @return {@link Map }<{@link String }, {@link Object }>
     * @author zhongzy
     * @date 2024/05/16
     */

    private Map<String, Object> addPrefixToProperties(Map<String, Object> properties, String prefix) {
        Map<String, Object> prefixedProperties = new HashMap<>();
        for (Map.Entry<String, Object> entry : properties.entrySet()) {
            String prefixedKey = prefix + entry.getKey();
            prefixedProperties.put(prefixedKey, entry.getValue());
        }
        return prefixedProperties;
    }
    private void addPropertiesToParameters(Map<String, Object> parameters, Map<String, Object> properties) {
        if (properties != null) {
            parameters.putAll(properties);
        }
    }

测试代码

    @Test
    public void test03() {
        //生成单个节点,这个只能传入一个属性名和属性值
        neo4jUtil.createNode("person", "name", "唐僧");
        neo4jUtil.createNode("person", "name", "孙悟空");
        neo4jUtil.createNode("person", "name", "猪八戒");
        neo4jUtil.createNode("person", "name", "沙僧");
    }

    @Test
    public void test04() {
        //生成多个节点,传入属性名和属性值的map
        Map<String, Object> nodeProperty = new HashMap<>();
        nodeProperty.put("name", "雷军");
        nodeProperty.put("car", "su7");
        neo4jUtil.createNode("小米", nodeProperty);
    }

    @Test
    public void test05() {
        Map<String, Object> map = new HashMap<>();
        map.put("name","唐僧");
        Map<String, Object> map1 = new HashMap<>();
        map1.put("name","孙悟空");
        Map<String, Object> relationMap = new HashMap<>();
        relationMap.put("year","2024");
        neo4jUtil.createRelationship("person",map,"person",map1,"徒弟",relationMap);
    }

效果达成,解决上篇文章中得问题!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值