SpringBoot結(jié)合Neo4j自定義cypherSql的方法
前言
SpringBoot引入neo4j
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-neo4j</artifactId> </dependency>
<spring.boot.version>2.2.11.RELEASE</spring.boot.version>
大多數(shù)時(shí)候Neo4j結(jié)合springboot都是按照實(shí)體類的映射,進(jìn)行對(duì)象形式的創(chuàng)建節(jié)點(diǎn),導(dǎo)致了節(jié)點(diǎn)屬性的不可配性。結(jié)合這種問(wèn)題,結(jié)合目前開(kāi)發(fā)經(jīng)驗(yàn),可以使用neo4j 框架的session 進(jìn)行原生cypherSql的執(zhí)行。所以結(jié)合使用session進(jìn)行動(dòng)態(tài)可配等思路,建立一個(gè)Neo4jUtil..
Neo4jUtil作用
SpringBoot結(jié)合neo4j,自定義封裝cypherSql進(jìn)行操作。實(shí)際就是使用neo4j的Session.執(zhí)行一些cypherSql操作,然后封裝了一些方法供大家在既可以使用springboot的對(duì)象化操作方式的前提創(chuàng)建節(jié)點(diǎn)或者關(guān)系,也可以自定義繼續(xù)封裝一些特殊需求的方法,避免大家造輪子。
相關(guān)代碼
application.yml
spring: data: neo4j: uri: bolt://127.0.0.1:7688 username: neo4j password: neo4j
config
package com.troy.keeper.modules.desk.config; import org.neo4j.ogm.session.SessionFactory; import org.springframework.beans.factory.annotation.Value; 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("com.troy.keeper.desc.repository") // 聲明neo4j repository存放地址 public class Neo4jConfig { @Value("${spring.data.neo4j.uri}") private String uri; @Value("${spring.data.neo4j.username}") private String userName; @Value("${spring.data.neo4j.password}") private String password; @Bean public org.neo4j.ogm.config.Configuration getConfiguration() { org.neo4j.ogm.config.Configuration configuration = new org.neo4j.ogm.config.Configuration.Builder().uri(uri).connectionPoolSize(100).credentials(userName, password).withBasePackages("com.troy.keeper.desc.repository").build(); return configuration; } @Bean public SessionFactory sessionFactory() { return new SessionFactory(getConfiguration()); } @Bean("neo4jTransaction") public Neo4jTransactionManager neo4jTransactionManager(SessionFactory sessionFactory) { return new Neo4jTransactionManager(sessionFactory); } }
Entity
Neo4jBasicNode
//節(jié)點(diǎn)實(shí)體類 package com.troy.keeper.modules.desk.entity.neo4j; import lombok.Data; import java.io.Serializable; import java.util.List; import java.util.Map; /** * neo4j 節(jié)點(diǎn)實(shí)體類 * @author YangBM */ @Data public class Neo4jBasicNode implements Serializable { private static final long serialVersionUID = 1L; /** * id */ private Long id; /** * 標(biāo)簽 */ private List<String> labels; /** * 標(biāo)簽屬性 */ private Map<String, Object> property; }
Neo4jBaiscRelation
//關(guān)系實(shí)體類 package com.troy.keeper.modules.desk.entity.neo4j; import lombok.Data; import java.io.Serializable; import java.util.Map; /** * 關(guān)系 */ @Data public class Neo4jBaiscRelation implements Serializable { private static final long serialVersionUID = 1L; /** * id */ private Long id; /** * 標(biāo)簽 */ private String type; /** * 標(biāo)簽屬性 */ private Map<String, Object> property; }
Neo4jQueryRelation
//查詢關(guān)系的時(shí)候返回的對(duì)象封裝的實(shí)體類 package com.troy.keeper.modules.desk.entity.neo4j; import lombok.Data; import java.io.Serializable; import java.util.Map; /** * 關(guān)系 * @author YangBM */ @Data public class Neo4jQueryRelation implements Serializable { private static final long serialVersionUID = 1L; /** * 開(kāi)始節(jié)點(diǎn)id */ private Long start; /** * 結(jié)束節(jié)點(diǎn)id */ private Long end; /** * 關(guān)系類型 */ private String type; /** * id */ private Long id; /** * 標(biāo)簽屬性 */ private Map<String, Object> property; }
VO
Neo4jBasicRelationReturnVO
package com.troy.keeper.modules.desk.vo.neo4j; import com.troy.keeper.modules.desk.entity.neo4j.Neo4jBasicNode; import com.troy.keeper.modules.desk.entity.neo4j.Neo4jQueryRelation; import lombok.Data; import java.io.Serializable; /** * 基礎(chǔ)返回關(guān)系VO * 關(guān)系 * @author YangBM */ @Data public class Neo4jBasicRelationReturnVO implements Serializable { private static final long serialVersionUID = 1L; private Neo4jBasicNode start; private Neo4jQueryRelation relationship; private Neo4jBasicNode end; }
RelationVO
package com.troy.keeper.modules.desk.vo.neo4j; import lombok.Data; /** * 將關(guān)系的實(shí)體類,轉(zhuǎn)換換成cypherSql需要字符串類型的vo * Util里面會(huì)用到 * @author YangBM */ @Data public class RelationVO { /** * 關(guān)系名稱 */ private String relationLabelName; /** * 開(kāi)始標(biāo)簽名稱 */ private String startLabelName; /** * 開(kāi)始節(jié)點(diǎn)條件 */ private String startNodeProperties; /** * 關(guān)系的屬性 */ private String relationProperties; /** * 結(jié)束節(jié)點(diǎn)條件 */ private String endNodeProperties; /** * 結(jié)束標(biāo)簽名稱 */ private String endLabelName; /** * 查詢層級(jí) */ private String level; }
Util
Neo4jUtil
package com.troy.keeper.modules.desk.util; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.ObjectMapper; import com.troy.keeper.core.tool.utils.BeanUtil; import com.troy.keeper.core.tool.utils.Func; import com.troy.keeper.modules.desk.dto.neo4j.Neo4jSaveRelationDTO; import com.troy.keeper.modules.desk.dto.neo4j.RelationDTO; import com.troy.keeper.modules.desk.entity.neo4j.Neo4jBaiscRelation; import com.troy.keeper.modules.desk.entity.neo4j.Neo4jBasicNode; import com.troy.keeper.modules.desk.entity.neo4j.Neo4jQueryRelation; import com.troy.keeper.modules.desk.vo.neo4j.Neo4jBasicRelationReturnVO; import com.troy.keeper.modules.desk.vo.neo4j.RelationVO; import lombok.SneakyThrows; import org.apache.commons.collections.IteratorUtils; import org.apache.commons.lang3.StringUtils; import org.neo4j.driver.internal.InternalPath; import org.neo4j.driver.types.Node; import org.neo4j.driver.types.Relationship; import org.neo4j.ogm.model.Property; import org.neo4j.ogm.model.Result; import org.neo4j.ogm.response.model.NodeModel; import org.neo4j.ogm.session.Session; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.*; /** * @author YangBM * Neo4J工具類 */ @Component public class Neo4jUtil { /** * init map序列號(hào) */ private static final ObjectMapper mapper = new ObjectMapper(); static { mapper.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false); } @SneakyThrows public static String propertiesMapToPropertiesStr(Map<String,Object> map) { map.entrySet().removeIf(entry -> Func.isEmpty(entry.getValue())); return mapper.writeValueAsString(map); } @Resource private Session session; public Session getSession() { return this.session; } /** * 獲取所有的標(biāo)簽名稱 * * @return */ public List<String> getAllLabelName() { String cypherSql = "match (n) return distinct labels(n) as name"; Result query = session.query(cypherSql, new HashMap<>()); ArrayList<String> labelNames = new ArrayList<>(); for (Map<String, Object> map : query.queryResults()) { String[] names = (String[]) map.get("name"); for (String name : names) { labelNames.add(name); } } return labelNames; } /** * 獲取所有的關(guān)系名稱 * * @return */ public List<String> getAllRelationName() { String cypherSql = "MATCH ()-[r]-() RETURN distinct type(r) as name"; Result query = session.query(cypherSql, new HashMap<>()); ArrayList<String> relationNames = new ArrayList<>(); for (Map<String, Object> map : query.queryResults()) { relationNames.add(map.get("name").toString()); } return relationNames; } /** * 按條件查詢節(jié)點(diǎn) * * @param node * @return 返回節(jié)點(diǎn)集合 */ public List<Neo4jBasicNode> queryNode(Neo4jBasicNode node) { String cypherSql = ""; if (Func.isNotEmpty(node.getId())) { cypherSql = String.format("MATCH (n) where id(n)=%s return n", node.getId()); } else { String labels = ""; if (Func.isNotEmpty(node.getLabels())) { labels = ":`" + String.join("`:`", node.getLabels()) + "`"; } String property = ""; if (Func.isNotEmpty(node.getProperty())) { property = Neo4jUtil.propertiesMapToPropertiesStr(node.getProperty()); } cypherSql = String.format("match(n%s%s) return n", labels, property); } Result query = session.query(cypherSql, new HashMap<>()); ArrayList<Neo4jBasicNode> nodeList = new ArrayList<>(); Iterable<Map<String, Object>> maps = query.queryResults(); for (Map<String, Object> map : maps) { NodeModel queryNode = (NodeModel) map.get("n"); Neo4jBasicNode startNodeVo = new Neo4jBasicNode(); startNodeVo.setId(queryNode.getId()); startNodeVo.setLabels(Arrays.asList(queryNode.getLabels())); List<Property<String, Object>> propertyList = queryNode.getPropertyList(); HashMap<String, Object> proMap = new HashMap<>(); for (Property<String, Object> stringObjectProperty : propertyList) { if (proMap.containsKey(stringObjectProperty.getKey())) { throw new RuntimeException("數(shù)據(jù)重復(fù)"); } proMap.put(stringObjectProperty.getKey(), stringObjectProperty.getValue()); } startNodeVo.setProperty(proMap); nodeList.add(startNodeVo); } session.clear(); return nodeList; } /** * 創(chuàng)建節(jié)點(diǎn) * * @param node 節(jié)點(diǎn) * @param nodup 是否去重。 true去重 false不去重 * @return */ public boolean createNode(Neo4jBasicNode node, Boolean nodup) { String labels = ""; if (Func.isNotEmpty(node.getLabels())) { labels = ":`" + String.join("`:`", node.getLabels()) + "`"; } String property = ""; if (Func.isNotEmpty(node.getProperty())) { property = Neo4jUtil.propertiesMapToPropertiesStr(node.getProperty()); } String cypherSql = String.format("%s(%s%s)", nodup ? "MERGE" : "create", labels, property); Result query = session.query(cypherSql, new HashMap<>()); session.clear(); return query.queryStatistics().getNodesCreated() > 0; } /** * 創(chuàng)建節(jié)點(diǎn)(不去重) * * @param node 節(jié)點(diǎn) * @param * @return */ public boolean createNode(Neo4jBasicNode node) { return this.createNode(node, false); } /** * 創(chuàng)建節(jié)點(diǎn),(去重增強(qiáng)型) * 創(chuàng)建節(jié)點(diǎn),如果節(jié)點(diǎn)存在,先把它刪除,在重新創(chuàng)建 * 這個(gè)方法的目的是因?yàn)?createNode方法所謂的去重,是指如果 ,已有節(jié)點(diǎn)A,需要?jiǎng)?chuàng)建的節(jié)點(diǎn)B,如果A的屬性個(gè)數(shù)大于B的屬性且屬性對(duì)應(yīng)的值一模一樣,就會(huì)創(chuàng)建一個(gè)新的A。所以現(xiàn)在的方式是對(duì)B新增A中B缺少的屬性 * @param node * @return */ public boolean recreateNode(Neo4jBasicNode node){ List<String> saveLabels = node.getLabels(); Map<String, Object> saveProperty = node.getProperty(); Set<String> savePropertyKeySet = saveProperty.keySet(); //查詢用屬性查詢節(jié)點(diǎn)是不是存在。 //存在比較標(biāo)簽的lable1是不是一樣。不一樣就這個(gè)查詢到的節(jié)點(diǎn)(少了就新增標(biāo)簽,多了就刪除標(biāo)簽) Neo4jBasicNode queryNode= BeanUtil.copy(node,Neo4jBasicNode.class); queryNode.setLabels(null); List<Neo4jBasicNode> queryNodeList = this.queryNode(queryNode); if (queryNodeList.isEmpty()){ return createNode(node,true); } for (Neo4jBasicNode neo4jBasicNode : queryNodeList) { //處理標(biāo)簽 List<String> queryLabels = neo4jBasicNode.getLabels(); ArrayList<String> addLabels = new ArrayList<>(); for (String saveLabel : saveLabels) { if (!queryLabels.contains(saveLabel)){ //新增標(biāo)簽 addLabels.add(saveLabel); } } String addLabelStr=addLabels.isEmpty()?"":("e:"+String.join(":",addLabels)); //處理屬性 Map<String, Object> queryProperty = neo4jBasicNode.getProperty(); Set<String> queryPropertyKeySet = queryProperty.keySet(); HashMap<String, Object> addPropertyMap = new HashMap<>(); for (String savePropertyKey: savePropertyKeySet) { if (!queryPropertyKeySet.contains(savePropertyKey)){ addPropertyMap.put(savePropertyKey,saveProperty.get(savePropertyKey)); } } String addPropertyStr=addPropertyMap.isEmpty()?"":(",e+="+ Neo4jUtil.propertiesMapToPropertiesStr(addPropertyMap)); if(StringUtils.isAllEmpty(addPropertyStr,addPropertyStr)){ return true; } String addLabelCypherSql =String.format("MERGE (e) with e where id(e)=%s set %s %s return count(e) as count",neo4jBasicNode.getId(),addLabelStr,addPropertyStr); Result query = session.query(addLabelCypherSql, new HashMap<>()); System.out.println("跟新了:"+neo4jBasicNode.getId()); session.clear(); } //創(chuàng)建不重復(fù)節(jié)點(diǎn) return true; }; /** * 批量創(chuàng)建節(jié)點(diǎn)(存在的節(jié)點(diǎn)將會(huì)被重復(fù)創(chuàng)建) * * @param nodeList 節(jié)點(diǎn)的list集合 * @return 創(chuàng)建成功條數(shù) * */ public Long batchCreateNode(List<Neo4jBasicNode> nodeList) { return this.batchCreateNode(nodeList, false); } /** * 批量創(chuàng)建節(jié)點(diǎn) * * @param nodeList 節(jié)點(diǎn)的list集合 * @param nodup 是否去重。 true去重(存在的節(jié)點(diǎn)將不會(huì)被創(chuàng)建) false不去重 * @return 創(chuàng)建成功條數(shù) */ public Long batchCreateNode(List<Neo4jBasicNode> nodeList, Boolean nodup) { ArrayList<Neo4jBasicNode> addNode = new ArrayList<>(); //驗(yàn)證 for (Neo4jBasicNode neo4jBasicNode : nodeList) { if ((!nodup) || this.queryNode(neo4jBasicNode).size() == 0) { addNode.add(neo4jBasicNode); } } String cypherSql = "create"; ArrayList<String> content = new ArrayList<>(); for (Neo4jBasicNode node : addNode) { String labels = ""; if (Func.isNotEmpty(node.getLabels())) { labels = ":`" + String.join("`:`", node.getLabels()) + "`"; } String property = ""; if (Func.isNotEmpty(node.getProperty())) { property = Neo4jUtil.propertiesMapToPropertiesStr(node.getProperty()); } content.add(String.format("(%s%s)", labels, property)); } cypherSql += String.join(",", content); if (content.size() == 0) { return 0L; } Result query = session.query(cypherSql, new HashMap<>()); session.clear(); return Long.valueOf(query.queryStatistics().getNodesCreated()); } /** * 刪除節(jié)點(diǎn)和相關(guān)關(guān)系 * * @param node 節(jié)點(diǎn)條件 * @param delRelation true 刪除節(jié)點(diǎn)相關(guān)的關(guān)系;false 只刪除不存在關(guān)系的,存在關(guān)系的節(jié)點(diǎn)將不會(huì)被刪除關(guān)系 * @return */ public Integer delNode(Neo4jBasicNode node, boolean delRelation) { String cypherSql = ""; if (Func.isNotEmpty(node.getId())) { cypherSql = String.format("MATCH (n) where id(n)=%s ", node.getId()); } else { String labels = ""; if (Func.isNotEmpty(node.getLabels())) { labels = ":`" + String.join("`:`", node.getLabels()) + "`"; } String property = ""; if (Func.isNotEmpty(node.getProperty())) { property = Neo4jUtil.propertiesMapToPropertiesStr(node.getProperty()); } cypherSql = String.format("match(n%s%s) ", labels, property); } if (delRelation) { cypherSql += "DETACH DELETE n"; } else { //刪除不存在關(guān)系的節(jié)點(diǎn) cypherSql += " where not exists((n)-[]-()) DELETE n"; } Result query = session.query(cypherSql, new HashMap<>()); session.clear(); return query.queryStatistics().getNodesDeleted(); } /** * 刪除節(jié)點(diǎn)和相關(guān)關(guān)系 * 只刪除不存在關(guān)系的,存在關(guān)系的節(jié)點(diǎn)將不會(huì)被刪除關(guān)系 * * @param node 節(jié)點(diǎn)條件 有關(guān)系的節(jié)點(diǎn)不會(huì)刪除 * @return */ public Integer delNode(Neo4jBasicNode node) { return this.delNode(node, false); } public int queryNodeCreateRelation(Neo4jBasicNode start, Neo4jBasicNode end, Neo4jBaiscRelation relation) { Neo4jSaveRelationDTO dto = new Neo4jSaveRelationDTO(); dto.setStart(start); dto.setEnd(end); dto.setRelationship(relation); return queryNodeCreateRelation(dto); } /** * 查詢節(jié)點(diǎn)然后創(chuàng)建關(guān)系 * 創(chuàng)建關(guān)系(查詢開(kāi)始節(jié)點(diǎn)和結(jié)束節(jié)點(diǎn)然后創(chuàng)造關(guān)系) * 注意:開(kāi)始節(jié)點(diǎn)和結(jié)束節(jié)點(diǎn)以及創(chuàng)建的關(guān)系參數(shù)一定要存在! * 關(guān)系如果存在,不會(huì)重復(fù)創(chuàng)建 * 因?yàn)樾枰祷貏?chuàng)建條數(shù) 當(dāng)前方法未做條件判斷 * * @param saveRelation 關(guān)系構(gòu)造類 * @return 返回創(chuàng)建關(guān)系的個(gè)數(shù) */ public int queryNodeCreateRelation(Neo4jSaveRelationDTO saveRelation) { //開(kāi)始節(jié)點(diǎn)和結(jié)束節(jié)點(diǎn)驗(yàn)證 String cypherSql = ""; String startLable = ""; if (Func.isNotEmpty(saveRelation.getStart().getLabels())) { startLable = ":`" + String.join("`:`", saveRelation.getStart().getLabels()) + "`"; } String startProperty = ""; if (Func.isNotEmpty(saveRelation.getStart().getProperty())) { startProperty = Neo4jUtil.propertiesMapToPropertiesStr(saveRelation.getStart().getProperty()); } String endLable = ""; if (Func.isNotEmpty(saveRelation.getEnd().getLabels())) { endLable = ":`" + String.join("`:`", saveRelation.getEnd().getLabels()) + "`"; } String endProperty = ""; if (Func.isNotEmpty(saveRelation.getEnd().getProperty())) { endProperty = Neo4jUtil.propertiesMapToPropertiesStr(saveRelation.getEnd().getProperty()); } String startWhere = ""; if (Func.isNotEmpty(saveRelation.getStart().getId())) { startWhere += " where id(start)=" + saveRelation.getStart().getId(); startLable = ""; startProperty = ""; } String endWhere = ""; if (Func.isNotEmpty(saveRelation.getEnd().getId())) { endWhere += " where id(end)=" + saveRelation.getEnd().getId(); endLable = ""; endProperty = ""; } String relationType = ""; if (Func.isNotEmpty(saveRelation.getRelationship().getType())) { relationType = ":`" + saveRelation.getRelationship().getType() + "`"; } if (Func.isEmpty(relationType)) { throw new RuntimeException("關(guān)系名稱不能為空!"); } String relationProperty = ""; if (Func.isNotEmpty(saveRelation.getRelationship().getProperty())) { relationProperty = Neo4jUtil.propertiesMapToPropertiesStr(saveRelation.getRelationship().getProperty()); } cypherSql = String.format("MATCH (start%s%s) %s with start MATCH (end%s%s) %s MERGE (start)-[rep%s%s]->(end)", startLable, startProperty, startWhere, endLable, endProperty, endWhere, relationType, relationProperty); Result query = session.query(cypherSql, new HashMap<>()); session.clear(); return query.queryStatistics().getRelationshipsCreated(); } /** * 創(chuàng)建節(jié)點(diǎn)同時(shí)創(chuàng)建關(guān)系 * 重復(fù)的不會(huì)被創(chuàng)建 * * @param saveRelation * @return */ public boolean creteNodeAndRelation(Neo4jSaveRelationDTO saveRelation) { String cypherSql = ""; String startLable = ""; if (Func.isNotEmpty(saveRelation.getStart().getLabels())) { startLable = ":`" + String.join("`:`", saveRelation.getStart().getLabels()) + "`"; } String startProperty = ""; if (Func.isNotEmpty(saveRelation.getStart().getProperty())) { startProperty = Neo4jUtil.propertiesMapToPropertiesStr(saveRelation.getStart().getProperty()); } String endLable = ""; if (Func.isNotEmpty(saveRelation.getEnd().getLabels())) { endLable = ":`" + String.join("`:`", saveRelation.getEnd().getLabels()) + "`"; } String endProperty = ""; if (Func.isNotEmpty(saveRelation.getEnd().getProperty())) { endProperty = Neo4jUtil.propertiesMapToPropertiesStr(saveRelation.getEnd().getProperty()); } String relationType = ""; if (Func.isNotEmpty(saveRelation.getRelationship().getType())) { relationType = ":`" + saveRelation.getRelationship().getType() + "`"; } if (Func.isEmpty(relationType)) { throw new RuntimeException("關(guān)系名稱不能為空!"); } String relationProperty = ""; if (Func.isNotEmpty(saveRelation.getRelationship().getProperty())) { relationProperty = Neo4jUtil.propertiesMapToPropertiesStr(saveRelation.getRelationship().getProperty()); } cypherSql = String.format("MERGE (start%s%s)-[rep%s%s]->(end%s%s)", startLable, startProperty, relationType, relationProperty, endLable, endProperty); Result query = session.query(cypherSql, new HashMap<>()); session.clear(); return query.queryStatistics().getRelationshipsCreated() > 0; } /** * 查詢關(guān)系 * * @param relationDTO * @return */ public List<Neo4jBasicRelationReturnVO> queryRelation(RelationDTO relationDTO) { RelationVO relationVO = formatRelation(relationDTO); //拼接sql String cypherSql = String.format("MATCH p=(a%s%s)-[r%s%s]->(b%s%s)-[*0..%s]->() RETURN p", relationVO.getStartLabelName(), relationVO.getStartNodeProperties(), relationVO.getRelationLabelName(), relationVO.getRelationProperties(), relationVO.getEndLabelName(), relationVO.getEndNodeProperties(), relationVO.getLevel()); System.out.println(cypherSql); long startTime = System.currentTimeMillis(); Result query = session.query(cypherSql, new HashMap<>()); System.out.println(String.format("耗時(shí)%d秒", System.currentTimeMillis() - startTime)); Iterable<Map<String, Object>> maps = query.queryResults(); ArrayList<Neo4jBasicRelationReturnVO> returnList = new ArrayList<>(); for (Map<String, Object> map : maps) { InternalPath.SelfContainedSegment[] ps = (InternalPath.SelfContainedSegment[]) map.get("p"); for (InternalPath.SelfContainedSegment p : ps) { returnList.add(changeToNeo4jBasicRelationReturnVO(p)); } } session.clear(); return returnList; } /** * 格式化 * * @param relationDTO * @return */ public RelationVO formatRelation(RelationDTO relationDTO) { RelationVO relationVO = new RelationVO(); //驗(yàn)證 if (Func.isNotEmpty(relationDTO.getRelationLabelName())) { relationVO.setRelationLabelName(":`" + relationDTO.getRelationLabelName()+"`"); } else { relationVO.setRelationLabelName(""); } if (Func.isNotEmpty(relationDTO.getStartLabelName())) { relationVO.setStartLabelName(":`" + relationDTO.getStartLabelName()+"`"); } else { relationVO.setStartLabelName(""); } if (Func.isNotEmpty(relationDTO.getEndLabelName())) { relationVO.setEndLabelName(":`" + relationDTO.getEndLabelName()+"`"); } else { relationVO.setEndLabelName(""); } if (Func.isNotEmpty(relationDTO.getStartNodeProperties())) { relationVO.setStartNodeProperties(Neo4jUtil.propertiesMapToPropertiesStr(relationDTO.getStartNodeProperties())); } else { relationVO.setStartNodeProperties(""); } if (Func.isNotEmpty(relationDTO.getRelationProperties())) { relationVO.setRelationProperties(Neo4jUtil.propertiesMapToPropertiesStr(relationDTO.getRelationProperties())); } else { relationVO.setRelationProperties(""); } if (Func.isNotEmpty(relationDTO.getEndNodeProperties())) { relationVO.setEndNodeProperties(Neo4jUtil.propertiesMapToPropertiesStr(relationDTO.getEndNodeProperties())); } else { relationVO.setEndNodeProperties(""); } if (Func.isNotEmpty(relationDTO.getLevel())) { relationVO.setLevel(relationDTO.getLevel().toString()); } else { relationVO.setLevel(""); } return relationVO; } /** * 轉(zhuǎn)化neo4j默認(rèn)查詢的參數(shù)為自定返回類型 * * @param selfContainedSegment * @return Neo4jBasicRelationReturn */ public Neo4jBasicRelationReturnVO changeToNeo4jBasicRelationReturnVO(InternalPath.SelfContainedSegment selfContainedSegment) { Neo4jBasicRelationReturnVO neo4JBasicRelationReturnVO = new Neo4jBasicRelationReturnVO(); //start Node start = selfContainedSegment.start(); Neo4jBasicNode startNodeVo = new Neo4jBasicNode(); startNodeVo.setId(start.id()); startNodeVo.setLabels(IteratorUtils.toList(start.labels().iterator())); startNodeVo.setProperty(start.asMap()); neo4JBasicRelationReturnVO.setStart(startNodeVo); //end Node end = selfContainedSegment.end(); Neo4jBasicNode endNodeVo = new Neo4jBasicNode(); endNodeVo.setId(end.id()); endNodeVo.setLabels(IteratorUtils.toList(end.labels().iterator())); endNodeVo.setProperty(end.asMap()); neo4JBasicRelationReturnVO.setEnd(endNodeVo); //relationship Neo4jQueryRelation neo4JQueryRelation = new Neo4jQueryRelation(); Relationship relationship = selfContainedSegment.relationship(); neo4JQueryRelation.setStart(relationship.startNodeId()); neo4JQueryRelation.setEnd(relationship.endNodeId()); neo4JQueryRelation.setId(relationship.id()); neo4JQueryRelation.setType(relationship.type()); neo4JQueryRelation.setProperty(relationship.asMap()); neo4JBasicRelationReturnVO.setRelationship(neo4JQueryRelation); return neo4JBasicRelationReturnVO; } }
到此這篇關(guān)于SpringBoot結(jié)合Neo4j自定義cypherSql的文章就介紹到這了,更多相關(guān)SpringBoot自定義cypherSql內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
IDEA導(dǎo)入外部項(xiàng)目報(bào)Error:java: 無(wú)效的目標(biāo)發(fā)行版: 11的解決方法
這篇文章主要介紹了IDEA導(dǎo)入外部項(xiàng)目報(bào)Error:java: 無(wú)效的目標(biāo)發(fā)行版: 11,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09SpringCloud之監(jiān)控?cái)?shù)據(jù)聚合Turbine的實(shí)現(xiàn)
這篇文章主要介紹了SpringCloud之監(jiān)控?cái)?shù)據(jù)聚合Turbine的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08springboot實(shí)現(xiàn)攔截器的3種方式及異步執(zhí)行的思考
實(shí)際項(xiàng)目中,我們經(jīng)常需要輸出請(qǐng)求參數(shù),響應(yīng)結(jié)果,方法耗時(shí),統(tǒng)一的權(quán)限校驗(yàn)等。本文首先為大家介紹 HTTP 請(qǐng)求中三種常見(jiàn)的攔截實(shí)現(xiàn),并且比較一下其中的差異。感興趣的可以了解一下2021-07-07簡(jiǎn)談java并發(fā)FutureTask的實(shí)現(xiàn)
這篇文章主要介紹了簡(jiǎn)談java并發(fā)FutureTask的實(shí)現(xiàn),FutureTask都是用于獲取線程執(zhí)行的返回結(jié)果。文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,,需要的朋友可以參考下2019-06-06詳解java動(dòng)態(tài)代理的2種實(shí)現(xiàn)方式
目前Java開(kāi)發(fā)包中包含了對(duì)動(dòng)態(tài)代理的支持,但是其實(shí)現(xiàn)只支持對(duì)接口的的實(shí)現(xiàn)。這篇文章主要介紹了詳解java動(dòng)態(tài)代理的2種實(shí)現(xiàn)方式 ,有興趣的可以了解一下。2016-11-11SpringCloud 服務(wù)注冊(cè)和消費(fèi)實(shí)現(xiàn)過(guò)程
這篇文章主要介紹了SpringCloud 服務(wù)注冊(cè)和消費(fèi)實(shí)現(xiàn)過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07淺談java運(yùn)用注解實(shí)現(xiàn)對(duì)類中的方法檢測(cè)的工具
這篇文章主要介紹了淺談java運(yùn)用注解實(shí)現(xiàn)對(duì)類中的方法檢測(cè)的工具,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08Springmvc RequestMapping請(qǐng)求實(shí)現(xiàn)方法解析
這篇文章主要介紹了Springmvc RequestMapping請(qǐng)求實(shí)現(xiàn)方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09