那就寫在前面吧
上一篇博文中我們介紹了Neo4j獨(dú)特的查詢語言Cypher的用法魏割,了解了Cypher的用法之后澎羞,我們就可以自行安裝Neo4j然后在其自帶的瀏覽器客戶端使用Cypher查詢了。
默認(rèn)的訪問地址是:http://localhost:7474/,通過這種方式我們就能比較直觀的查看查詢結(jié)果。但是在實(shí)際的項(xiàng)目中,這種方式只能作為輔助践盼,我們實(shí)際要操作Neo4j有兩種主要的方式:java API、Spring Data Neo4j宾巍。使用java API的方式比較繁瑣咕幻,因此我們主要還是用Spring Data Neo4j來訪問圖數(shù)據(jù)庫。
Spring Data Neo4j簡介
Spring Data Neo4j是一個(gè)對(duì)象-圖形映射(OGM) 框架顶霞,是為了簡化開發(fā)者的工作而創(chuàng)建的(目前只有Java具有)肄程,或者說是滿足那些需要或者想要用它與基于POJO域模型工作的開發(fā)者锣吼,在這種情況下, 所有的數(shù)據(jù)都存儲(chǔ)在Neo4j中蓝厌。
它的目的是通過處理所有低層工作和從Neo4j讀域?qū)嶓w并寫回去所必需的映射邏輯來提高效率玄叠。這將使你騰出時(shí)間把重點(diǎn)放在寫代碼上——即業(yè)務(wù)邏輯。
作為Spring Data的子項(xiàng)目之一拓提,Spring Data Neo4j與其他的OGM框架一樣读恃,在項(xiàng)目中扮演著連接底層的Neo4j數(shù)據(jù)庫與域模型的重要角色。具體的架構(gòu)如下圖所示:
注意:SDN不適合一次處理任意類型的大量數(shù)據(jù)的場景代态。要加載或存儲(chǔ)的任何邏輯在一次操作中超過10000個(gè)單元對(duì)SDN來說不是一個(gè)好的選擇寺惫。另外,通過提供了一個(gè)間接層蹦疑,SDN會(huì)比僅僅使用核心API慢西雀,因此,如果速度和性能是考慮的最重要因素的話歉摧,最好還是使用其本身的API艇肴。
建立模型
模型主要包含了節(jié)點(diǎn)與關(guān)系的信息,其中節(jié)點(diǎn)依然是在普通的POJO對(duì)象上加上Neo4j獨(dú)有的注解來構(gòu)建叁温。
下面我們來看一個(gè)簡單的節(jié)點(diǎn)例子再悼,它表示一個(gè)作業(yè)Job
@NodeEntity
public class Job {
@GraphId
private Long id;
@Indexed
private String name;
private String description;
private String state;
private Job() {
// Empty constructor required as of Neo4j API 2.0.5
};
public Job(String name) {
this.name = name;
}
@Relationship(type = "DEPEND", direction = Relationship.UNDIRECTED)
public Set<Job> depends;
// getter and setter methods
。券盅。帮哈。
}
@NodeEntity 注解用于標(biāo)識(shí)它表示一個(gè)節(jié)點(diǎn),用于類的前面
@GraphId 可以理解為Neo4j自動(dòng)為節(jié)點(diǎn)生成的唯一性標(biāo)識(shí)Id
@Indexed 用于節(jié)點(diǎn)的屬性上锰镀,可以為該屬性創(chuàng)建索引,提高其查詢效率
關(guān)系實(shí)體的例子如下
@RelationshipEntity(type = "DEPEND")
public class depend {
@GraphId
private Long relationshipId;
@StartNode
Job startJob;
@EndNode
Job endJob;
private String property;
}
@RelationshipEntity 注解用于標(biāo)識(shí)它表示一個(gè)節(jié)點(diǎn)咖刃,用于類的前面泳炉。使用type可以關(guān)聯(lián)關(guān)系的名字"DEPEND"
@StartNode 表示關(guān)系的起始節(jié)點(diǎn)(關(guān)系出)
@EndNode 表示關(guān)系的終止節(jié)點(diǎn)(關(guān)系進(jìn))
上面的關(guān)系表示作業(yè)之間存在單向的依賴關(guān)系,這種比較簡單的關(guān)系可以不用專門創(chuàng)建一個(gè)關(guān)系類來標(biāo)識(shí)嚎杨,像上面Job節(jié)點(diǎn)中定義的那樣花鹅,我們可以使用一個(gè)注解來標(biāo)識(shí)這種關(guān)系
@Relationship(type = "DEPEND", direction = Relationship.UNDIRECTED)
創(chuàng)建Repository
如何能與這些實(shí)體交互和怎樣能加載并保存來自于或回到圖形數(shù)據(jù)庫中的POJO實(shí)體?
Spring Data Neo4j為我們提供了三種方式來實(shí)現(xiàn)枫浙。
① 支持Spring的配置
config入口做許多初始化工作刨肃,例如,可以將storeDirectory屬性作為一個(gè)方便的方式來引用圖形數(shù)據(jù)庫(如果數(shù)據(jù)庫不存在就創(chuàng)建一個(gè)新數(shù)據(jù)庫)箩帚。在SDN 3.0以前的版本中真友,使用base-package屬性指定域?qū)嶓w定義所在的目錄或目錄列表是強(qiáng)制性的。
② Neo4jTemplate類
Neo4jTemplate是一個(gè)SDN類紧帕,能用于實(shí)例化盔然,可以直接使用或當(dāng)Spring初始化時(shí)用于你的應(yīng)用程序桅打。通過充分利用具有依賴注入(DependencyInjection, DI)函數(shù)的Spring框架愈案,我們可以更加專注于業(yè)務(wù)邏輯挺尾,而不用關(guān)心更多的樣板代碼(如樣板事務(wù)代碼)。
③ 資源庫
Spring Data Neo4j為我們提供了資源庫的方式來封裝了常用的17種對(duì)模型的操作方法站绪,比如保存遭铺、刪除、按照id查詢等等恢准。我們要做的僅僅是創(chuàng)建一個(gè)接口魂挂,然后繼承GraphRepository接口,就可以使用資源庫中已經(jīng)封裝好的方法顷歌。
如果我們想要擴(kuò)展資源庫锰蓬,那么就需要在我們的接口中編寫新的業(yè)務(wù)方法來完成,這里可以使用注解@Query眯漩,然后編寫具體的Cypher語句芹扭。
下面是一個(gè)例子:
public interface JobRepository extends GraphRepository<Job> {
Job findByName(@Param("name") String name);
// depth from 1 - 5,return job's name,path's length and node's name
// MATCH (n:Job) where n.name="PDM_F_T00_CNR_PARM" with n match p = (n) - [d:DEPEND*1..5] -> (m:Job) return m.name,length(p),extract(x in nodes(p) | x.name)
@Query("MATCH (n:Job) where n.name={name} with n match p = (n) - [d:DEPEND*1..5] -> (m:Job) return m")
Collection<Job> findDepthJob(@Param("name") String name);
}
可以看到在Cypher語句中是如何獲取參數(shù)name的赦抖,使用{name}就可以獲取下面方法中傳入的name參數(shù)了舱卡。
小結(jié)
這篇博文主要介紹了Spring Data Neo4j如何使用來簡化我們的開發(fā),通過這幾篇博文的介紹队萤,我們已經(jīng)了解了搭建一個(gè)簡單的Neo4j項(xiàng)目所需要的必備知識(shí)轮锥。想要了解更多Neo4j以及Spring Data Neo4j的信息,請(qǐng)前往它們的官網(wǎng)查看其官方文檔要尔。