Neo4J 安装&常见语句操作&项目中的集成应用&复杂查询(@Query注解和自定义Match)
来源:互联网 发布:网络电视机顶盒功能 编辑:程序博客网 时间:2024/06/05 17:42
I 安装Neo4J
1 准备工作
1.1 下载安装包--bin--Neo4J-ce.exe,执行Start1 准备工作
1.2 访问 http://localhos:7474/browser/
II 常见语句操作
II 常见语句操作
删除节点
MATCH(n:City) DETACH DELETE nMATCH(n:City {name="Wuhan"}) DETACH DELETE nSTART n = node(1) DELETE n
删除关系、节点关系
match (n)-[r:created]-() detach delete rmatch(o:Organ {organId:"1000"})-[r:ORGAN_ACCOUNT]->(c:Account{countId:"1"})detach delete rmatch(o:Organ {organId:"1000"})-[r:ORGAN_ACCOUNT]->(c:Account{countId:"1"})detach delete r,o,c查看节点
MATCH(n:City) DETACH RETURN n
查看关系
match (n)-[r:created]-() RETURN r
创建结点:create (:Person {name:"张三"}),创建一个名为张三的节点;
create (a:Equip{equipSn:'SC1',equipStatus:'1'})create (c:Account{countId:'1',Name:'CJ1',userName:'CJ去名称'})
创建结点关系:
create (n:Equip {equipSn:"SC1"})-[r:equip_Customer {bindStatus:"1"}]->(c:Customer {Id:"adminId",Name:"chenJ"}) return n,r,c;条件查询:
MATCH (n:BdEquipmentInfo)-[r:ISERVER_CUSTOMER]->(c:CfCustomer )WHERE 1 = 1 and n.equipmentSn= "SC1" And c.customerName =~ '.*nJAdmin.*' and r.bindStatus = '1' RETURN c ;修改属性值,给默认的根节点添加name,ID属性,便于查询
start a = node(*) where a.name="a" set a.name="A" return a,a.name ; start n=node(0) set n.name="Root",n.ID="001"
创建多个节点数据,多个元素间用逗号或者用create分开:
create (a:Person {name:"jiaj",born:2003})-[r:ACTED_IN {roles:["student"]}]->(m:School {name:"CDLG",address:"chengdu"})create (d:Person {name:"weiw",born:2001})-[:DIRECTED]->(m)return a,d,r,m;创建关系【在id=1和2的2个节点间】
CREATE (a:node(1))-[:ACTED_IN { roles: "Forrest"}]->(b:node(2))
官网: http://neo4j.com/docs/developer-manual/current/cypher/clauses/match/
III 项目中的集成应用
**************************************
III 项目中的集成应用
1 定义结点、关系(@NodeEntity、@RelationshipEntity)
结点关系图:
package com.domain.entity;@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")@NodeEntitypublic class BdApp{ @GraphId private Long id; private String appId; private String appName; private String appType; private String appClassId; //}@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")@NodeEntitypublic class BdAppVer{ @GraphId private Long id; private String appVerId; private String appVerNum; //}package com.domain.relationship;@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")@RelationshipEntity(type = "APP_VER")public class AppVerRelationship { @GraphId private Long id; @StartNode private BdApp bdApp; @EndNode private BdAppVer bdAppVer; private String memo; //}
**************************************
2 定义结点、关系持久化层
2.1 APP 结点 Code:
package com.mapper.entity;import org.springframework.data.neo4j.repository.GraphRepository;import org.springframework.stereotype.Repository;@Repositorypublic interface BdAppRepository extends GraphRepository<BdApp> { //1 可自动继承neo4j.repository.GraphRepository父类封装的各方法 //2自定义方法 BdApp findByAppId(String appId);}
附:结点持久化层的 继承关系图
2.2 AppVer结点Code
package com.mapper.relationship@Repositorypublic interface BdAppVerRepository extends GraphRepository<BdAppVer> { //3Query自定义属性模糊与精确查询,appVerName= ".*XXX.*" @Query("MATCH (bdAppVer:BdAppVer) " + "WHERE bdAppVer.appId={appId} AND bdAppVer.appVerName =~ {appVerName} " + "RETURN bdAppVer ORDER BY bdAppVer.appVerNum DESC ") List<BdAppVer> queryBdAppVer(String appId, String appVerName);}
2.3 关系AppVerRepository Code
@Repositorypublic interfaceAppVerRepositoryextendsGraphRepository<AppVerRelationship> {//同结点原理一致}
3 定义结点、关系Service层
3.1 BdAppService:
public interface BdAppService { /** * 创建BdApp */ BdApp createBdApp(BdApp bdApp); /** * 创建BdAppVer 和 关系AppVerRelationship */ BdAppVer createBdAppVer(String appId,BdAppVer bdAppVer);}
Impl:
@Service@Transactionalpublic class BdAppServiceImpl implements BdAppService { @Autowired private BdAppRepository bdAppRepository; @Autowired private BdAppVerRepository bdAppVerRepository; @Autowired private AppVerRepository appVerRepository;//关系Repository @Override public BdApp createBdApp(BdApp bdApp) { //bdApp.setAppId(UUID.randomUUID().toString()); bdAppRepository.save(bdApp); return bdApp; } @Overridepublic BdAppVer createBdAppVer(String appId, BdAppVer bdAppVer) { BdApp bdApp = bdAppRepository.findByAppId(appId); bdAppVer.setAppId(appId); bdAppVerRepository.save(bdAppVer); //建立关系 AppVerRelationship appVerRelationship = new AppVerRelationship();appVerRelationship.setBdApp(bdApp);appVerRelationship.setBdAppVer(bdAppVer);appVerRelationship.setMemo("");appVerRepository.save(appVerRelationship);}3.2 BdAppVerService&BdAppVerServiceImpl同上
4 SpringJUnit4测试 结点/结点关系的CURD
4.1 定义环境(ComponentScan、Configuration和初始化neo4j Jdbc)
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;import org.springframework.boot.autoconfigure.domain.EntityScan;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;import org.springframework.transaction.annotation.EnableTransactionManagement;@EnableAutoConfiguration@EnableNeo4jRepositories(basePackages = {"com.mapper.entity.", "com.mapper.relationship."})@EntityScan(basePackages = {"com.domain."})@EnableTransactionManagement@ComponentScan@Configurationpublic class CoreConfig{ @Bean public org.neo4j.ogm.config.Configuration getConfiguration(){ org.neo4j.ogm.config.Configuration config = new org.neo4j.ogm.config.Configuration(); config.driverConfiguration() .setDriverClassName("org.neo4j.ogm.drivers.http.driver.HttpDriver") .setURI("http://neo4j:neo4j@localhost:7474"); return config; }}
4.2 测试类:
import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;//应用模块测试@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes=CoreConfig.class)public class BdAppServiceTest { @Autowired public BdAppService bdAppService; @Test public void createBdAppTest(){ BdApp bdApp = new BdApp(); bdApp.setAppId("CJ1"); bdApp初始化值Set bdAppService.createBdApp(bdApp); } @Test public void createBdAppVerAndRelationshipTest(){ String appId = "CJ1"; BdAppVer appVer = new BdApp(); BdAppVer 初始化值Set bdAppService.createBdAppVer(appId ,bdApp); }}
5 实现复杂查询(如多条件分页查询&结点、关系组合查询等
5.1 Match执行复杂语句方式,执行@Query实现
5.2 自定义持久层Dao实现
**********************************************************************************
5.1 Code:
**********************************************************************************
5.1 Code:
1 实体、关系定义:
实体:
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")@NodeEntitypublic class Packcode{ @GraphId private Long id; private String packcodeNo;//当前包编号 private String parentPackcodeNo;//父(上级)包编号 private String packName; @Relationship(type= "Pc_LINK_Pc") private Set<PackCodeLinkPackRship> packCodeLinkPacks; }
关系:
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")@RelationshipEntity(type = "Pc_LINK_Pc")@QueryResultpublic class PackCodeLinkPackRship { @StartNode private Packcode bdPackcode; @EndNode private Packcode subBdPackcode; @GraphId private Long id; private String bindStatus;。。。}
2 Cypher语句查询实现
//2.1 获取packcodeNo 包所有子包(即下属树结点信息)@Query(" MATCH p=(p:Packcode)-[r:Pc_LINK_Pc*0..]->(subP:Packcode) " + " WHERE p.packcodeNo = {packcodeNo} " + " RETURN p")List<Packcode> loadPackcodeSubTree(@Param("packcodeNo") String packcodeNo);即:MATCH p=(p:Packcode)-[r:Pc_LINK_Pc*0..]->(subP:Packcode)WHERE p.packcodeNo = '1' RETURN p;*********************************************************//2.2获取packcodeNo 包所有父包且关系bindStatus=1@Query(" MATCH p=(s:Packcode)-[rp:Pc_LINK_Pc*0..]->(subP:Packcode) " + " WHERE subP.packcodeNo = {packcodeNo} and all( x in rp where x.bindStatus= {bindStatus} ) "+ " RETURN p ")List<Packcode> findAllParentPackcodeByPackcodeNoAndBindStatus(@Param("packcodeNo")String packcodeNo,@Param("bindStatus") String bindStatus);即:MATCH p=(s:Packcode)-[rp:Pc_LINK_Pc*0..]->(e:BdPackcode) WHERE e.packcodeNo = '3Sub' and all( x in rp where x.bindStatus='1' ) RETURN p;
***********************************************************************************
II)多条件分页查询(注意:雷同部分略)
I) 多条件查询(未分页)
1 定义App Dao接口
package com.mapper.neo4jdao.model;public interface BdAppDao { List<BdApp> queryBdAppByPerproty(BdApp bdApp);}
2 实现App Dao实现层
package com.mapper.neo4jdao.model.Impl;@Repositorypublic class BdAppDaoImpl implements BdAppDao { @Autowired Session session;//查询前缀private static final String QUERY_PREFFIX = "MATCH (bdApp:BdApp) ";private static final String QUERY_WHERE = " WHERE 1 = 1 ";@Overridepublic List<BdApp> queryBdAppByPerproty(BdApp bdApp) { Map<String, String> params = new HashMap<>(); String cypher = this.getListCypher(bdApp, params); if (StringUtils.isEmpty(cypher)) return null; Iterable<BdApp> its = session.query(BdApp.class, cypher, params); if (its == null) return null; List<BdApp> results = new ArrayList<>(); its.forEach((v) -> results.add(v)); return results;}/** * 构造查询型号的cypher语句 * @param queryParams 查询对象 * @return 返回cypher语句 */private String getListCypher(BdApp domain, Map<String, String> queryParams) { StringBuffer stringBuffer = new StringBuffer(QUERY_PREFFIX); stringBuffer.append(QUERY_WHERE); stringBuffer.append(midCypher(stringBuffer, domain, queryParams)); stringBuffer.append(" RETURN bdApp"); stringBuffer.append(" ORDER BY bdApp.appType,bdApp.appClassName,bdApp.appId ASC ");//(默认按照 类型、分类 、appid排序) return stringBuffer.toString();}/** * @param queryParams * @return */private String midCypher(StringBuffer sb, BdApp domain, Map<String, String> queryParams) { StringBuffer stringBuffer = new StringBuffer(); //多条件查询:类型APP_TYPE、分类 APP_CLASS_NAME、appid、名称APP_NAME、状态APP_STATUS if (!StringUtils.isEmpty(domain.getAppType())) { stringBuffer.append(" AND bdApp.appType = {aType}"); queryParams.put("aType", domain.getAppType()); } if (!StringUtils.isEmpty(domain.getAppClassId())) { stringBuffer.append(" AND bdApp.appClassId = {appCId}"); queryParams.put("appCId", domain.getAppClassId()); } if (!StringUtils.isEmpty(domain.getAppId())) { stringBuffer.append(" AND bdApp.appId = {aId}"); queryParams.put("aId", domain.getAppId()); } if (!StringUtils.isEmpty(domain.getAppName())) { stringBuffer.append(" AND bdApp.appName =~ {aName}"); queryParams.put("aName", ".*"+domain.getAppName()+"*."); } //状态APP_STATUS if (!StringUtils.isEmpty(domain.getAppStatus())) { stringBuffer.append(" AND bdApp.appStatus = {aStatus}"); queryParams.put("aStatus", domain.getAppStatus()); } return stringBuffer.toString();}
II)多条件分页查询(注意:雷同部分略)
1 Dao层
package com.mapper.neo4jdao.model;public interface BdAppDao { int getTotalBdApp(String cypher,Map<String,String> params); PageResult getBdAppPage(BdApp domain,Integer currPage, Integer pagesize);}
2 Dao 实现层
package com.mapper.neo4jdao.model.Impl;@Repositorypublic class BdAppDaoImpl implements BdAppDao { @Autowired Session session; //查询前缀 private static final String QUERY_PREFFIX = "MATCH (bdApp:BdApp) "; private static final String QUERY_WHERE = " WHERE 1 = 1 "; @Override public int getTotalBdApp(String cypher,Map<String,String> params) { return DaoUtil.getTotalNum(session,cypher,params); } @Override public PageResult getBdAppPage(BdApp bdApp,Integer page, Integer pagesize) { PageResult pr = new PageResult(); Map<String,String> params = new HashMap<>(); StringBuffer cypherbuf = new StringBuffer(this.midCypher(domain,params));//需要修改下 if(StringUtils.isEmpty(cypherbuf)){ return pr; } int totalnum = this.getTotalBdApp(cypherbuf+" RETURN count(c) as count",params); pr.setToltalsize(totalnum); pr.setPage(page); pr.setPagesize(pagesize); page = page==null|page<1?1:page; pagesize = pagesize == null | pagesize <1 ? 10:pagesize; int skip = (page-1)*(totalnum/pagesize); int limit = pagesize; cypherbuf.append(" RETURN c"); cypherbuf.append(" SKIP "); cypherbuf.append(skip); cypherbuf.append(" LIMIT "); cypherbuf.append(limit); Iterable<BdApp> its = session.query(BdApp.class,cypherbuf.toString(),params); if(its==null)return pr; List<BdApp> results = new ArrayList<>(); its.forEach((v)->results.add(v)); pr.addData(results); return pr; }}
3 分页基础类-DaoUtil,统计总记录数
public class DaoUtil { private DaoUtil(){} public static int getTotalNum(Session session,String cypher,Map<String,String> params){ Result result = session.query(cypher,params); int totalnum = 0; if(result==null)return totalnum; Iterator<Map<String,Object>> its = result.iterator(); while (its.hasNext()){ Map<String,Object> ret = its.next(); if(ret!=null){ Object nums = ret.getOrDefault("count",0); if( nums != null ){ totalnum = Integer.parseInt(nums.toString()); break; } } } return totalnum; }}
0 0
- Neo4J 安装&常见语句操作&项目中的集成应用&复杂查询(@Query注解和自定义Match)
- 项目中使用的自定义数据访问类(复杂查询,复杂操作)
- Elasticsearch查询-Match Query
- Neo4j CQL -(4)- MATCH & RETURN匹配和返回
- NutzDao-自定义SQL语句进行复杂查询
- query语句查询,and和or组合
- 自定义ORM注解实现生成查询语句
- 玩转SSH之Spring(一)---关于Spring框架中使用@query注解实现复杂查询
- Spring Data Jpa 使用@Query标注自定义查询语句
- Hibernate的Query接口和查询操作
- October query(数据库查询语句)
- SQL语句中的查询操作
- 操作Android中联系人,通话记录,短息,的URI,和具体的查询语句,字段注解。(根据自己需求)
- Cypher查询语言--Neo4j中的SQL(1)
- Cypher查询语言--Neo4j中的SQL(2)
- Cypher查询语言--Neo4j中的SQL(3)
- Cypher查询语言--Neo4j中的SQL(4)
- Cypher查询语言--Neo4j中的SQL(5)
- 关于Python的进程线程协程之threading模块(一)Thread类
- Linux cp
- Java 9 中的新特性
- log4j
- Eclipse去掉对JS文件的Validation
- Neo4J 安装&常见语句操作&项目中的集成应用&复杂查询(@Query注解和自定义Match)
- STL中list的各个接口的使用
- Incomplete history of a file in git (git-svn)
- UML序列图
- 大数据是什么和大数据技术十大核心原理详解
- Redis与Tomcat 简单Session共享
- 多线程:为什么在while循环中加入System.out.println,线程可以停止
- Jersey Politics POJ
- PHP中error_reporting()用法详解