那就寫在前面吧
上一篇博文中我們介紹了Neo4j獨特的查詢語言Cypher的用法,了解了Cypher的用法之后,我們就可以自行安裝Neo4j然后在其自帶的瀏覽器客戶端使用Cypher查詢了。
默認的訪問地址是:http://localhost:7474/,通過這種方式我們就能比較直觀的查看查詢結果。但是在實際的項目中,這種方式只能作為輔助,我們實際要操作Neo4j有兩種主要的方式:java API、Spring Data Neo4j。使用java API的方式比較繁瑣,因此我們主要還是用Spring Data Neo4j來訪問圖數據庫。
Spring Data Neo4j簡介
Spring Data Neo4j是一個對象-圖形映射(OGM) 框架,是為了簡化開發(fā)者的工作而創(chuàng)建的(目前只有Java具有),或者說是滿足那些需要或者想要用它與基于POJO域模型工作的開發(fā)者,在這種情況下, 所有的數據都存儲在Neo4j中。
它的目的是通過處理所有低層工作和從Neo4j讀域實體并寫回去所必需的映射邏輯來提高效率。這將使你騰出時間把重點放在寫代碼上——即業(yè)務邏輯。
作為Spring Data的子項目之一,Spring Data Neo4j與其他的OGM框架一樣,在項目中扮演著連接底層的Neo4j數據庫與域模型的重要角色。具體的架構如下圖所示:

注意:SDN不適合一次處理任意類型的大量數據的場景。要加載或存儲的任何邏輯在一次操作中超過10000個單元對SDN來說不是一個好的選擇。另外,通過提供了一個間接層,SDN會比僅僅使用核心API慢,因此,如果速度和性能是考慮的最重要因素的話,最好還是使用其本身的API。
建立模型
模型主要包含了節(jié)點與關系的信息,其中節(jié)點依然是在普通的POJO對象上加上Neo4j獨有的注解來構建。
下面我們來看一個簡單的節(jié)點例子,它表示一個作業(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 注解用于標識它表示一個節(jié)點,用于類的前面
@GraphId 可以理解為Neo4j自動為節(jié)點生成的唯一性標識Id
@Indexed 用于節(jié)點的屬性上,可以為該屬性創(chuàng)建索引,提高其查詢效率
關系實體的例子如下
@RelationshipEntity(type = "DEPEND")
public class depend {
@GraphId
private Long relationshipId;
@StartNode
Job startJob;
@EndNode
Job endJob;
private String property;
}
@RelationshipEntity 注解用于標識它表示一個節(jié)點,用于類的前面。使用type可以關聯(lián)關系的名字"DEPEND"
@StartNode 表示關系的起始節(jié)點(關系出)
@EndNode 表示關系的終止節(jié)點(關系進)
上面的關系表示作業(yè)之間存在單向的依賴關系,這種比較簡單的關系可以不用專門創(chuàng)建一個關系類來標識,像上面Job節(jié)點中定義的那樣,我們可以使用一個注解來標識這種關系
@Relationship(type = "DEPEND", direction = Relationship.UNDIRECTED)
創(chuàng)建Repository
如何能與這些實體交互和怎樣能加載并保存來自于或回到圖形數據庫中的POJO實體?
Spring Data Neo4j為我們提供了三種方式來實現(xiàn)。
① 支持Spring的配置
config入口做許多初始化工作,例如,可以將storeDirectory屬性作為一個方便的方式來引用圖形數據庫(如果數據庫不存在就創(chuàng)建一個新數據庫)。在SDN 3.0以前的版本中,使用base-package屬性指定域實體定義所在的目錄或目錄列表是強制性的。

② Neo4jTemplate類
Neo4jTemplate是一個SDN類,能用于實例化,可以直接使用或當Spring初始化時用于你的應用程序。通過充分利用具有依賴注入(DependencyInjection, DI)函數的Spring框架,我們可以更加專注于業(yè)務邏輯,而不用關心更多的樣板代碼(如樣板事務代碼)。

③ 資源庫
Spring Data Neo4j為我們提供了資源庫的方式來封裝了常用的17種對模型的操作方法,比如保存、刪除、按照id查詢等等。我們要做的僅僅是創(chuàng)建一個接口,然后繼承GraphRepository接口,就可以使用資源庫中已經封裝好的方法。

如果我們想要擴展資源庫,那么就需要在我們的接口中編寫新的業(yè)務方法來完成,這里可以使用注解@Query,然后編寫具體的Cypher語句。
下面是一個例子:
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語句中是如何獲取參數name的,使用{name}就可以獲取下面方法中傳入的name參數了。
小結
這篇博文主要介紹了Spring Data Neo4j如何使用來簡化我們的開發(fā),通過這幾篇博文的介紹,我們已經了解了搭建一個簡單的Neo4j項目所需要的必備知識。想要了解更多Neo4j以及Spring Data Neo4j的信息,請前往它們的官網查看其官方文檔。