Spring Data Neo4j(二)

什么是SDN

Spring Data Neo4j 簡稱SND,是一個對象-圖形映射(OGM)框架,是為了簡化開發(fā)者的工作而創(chuàng)建的诈铛,它的目的是通過處理所有底層工作和從Neo4j讀域?qū)嶓w并寫回去所必須的映射邏輯來提高效率

缺點

SND從很大程度上為開發(fā)者提供了方便的使用代碼和庫函數(shù),能非常方便的集成與Spring,但是SDN不適合一次處理任意類型的大量數(shù)據(jù)的場景澡屡,要加載或者存儲的任何邏輯在一次操作中超過10000個單元對SDN來說不是一個很好的選擇炼蛤。SDN相當(dāng)于充當(dāng)了一個間接層的妖爷,操作數(shù)量過大的話,相比原生的核心API會慢很多理朋。

SDN建模

假設(shè)現(xiàn)在有兩個節(jié)點流程(Process) and 任務(wù)(Task) 通過關(guān)系(PROCESS_IN)建立兩個節(jié)點的連接絮识,應(yīng)當(dāng)如何建模?

分析在工作流程業(yè)務(wù)中嗽上,** 流程(Process)實例** 與** 任務(wù)(Task)實例** 是一對多的關(guān)系次舌,一個任務(wù)只能有一個流程,一個流程包含多個任務(wù)兽愤。

在SDN中,節(jié)點彼念、關(guān)系 都可以用過注解來表示挪圾,非常方便

** @NodeEntity** 增加該注解屬性在類上,表示這是一個節(jié)點国拇。
** @GraphId ** 該節(jié)點的唯一編號洛史,會自動生成惯殊,跟mysql酱吝、oracle里面的id一個性質(zhì),是必須的土思。
** @Relationship(type = "")** 該屬性增加在節(jié)點的屬性上务热,該屬性必須為節(jié)點,type 表示連接他們的關(guān)系(Relationship)的名字己儒。
** @RelationshipEntity(type = "") ** 該注解增加在類上崎岂,表示他是一個關(guān)系(Relationship) type表示該關(guān)系的名字,不寫則默認類的名字闪湾。
** @StartNode ** 該屬性增加在關(guān)系的屬性上冲甘,該屬性必須為節(jié)點 表示該節(jié)點為起點節(jié)點。
** @EndNode** 該屬性增加在關(guān)系的屬性上途样,該屬性必須為節(jié)點 表示該節(jié)點為結(jié)束節(jié)點江醇。
注意:節(jié)點與節(jié)點的關(guān)系表述,必須要有明確的開始和結(jié)束何暇。

如下圖所示:

Paste_Image.png

流程實例與任務(wù)實例及連接他們的關(guān)系 在代碼中如下:

Process類:

@NodeEntity
public class Process {

    @GraphId
    private Long id;

    @Relationship(type = "PROCESS_IN")
    private List<Task> tasks;

    private String processName;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public List<Task> getTasks() {
        return tasks;
    }

    public void setTasks(List<Task> tasks) {
        this.tasks = tasks;
    }

    public String getProcessName() {
        return processName;
    }

    public void setProcessName(String processName) {
        this.processName = processName;
    }
}

Task類:

@NodeEntity
public class Task {

    @GraphId
    private Long id;

    private String taskName;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTaskName() {
        return taskName;
    }

    public void setTaskName(String taskName) {
        this.taskName = taskName;
    }
}

關(guān)系(PROCESS_IN)

@RelationshipEntity(type = "PROCESS_IN")
public class ProcessIn {

    @GraphId
    private Long id;

    @StartNode
    private Process process;
    @EndNode
    private Task task;


    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Process getProcess() {
        return process;
    }

    public void setProcess(Process process) {
        this.process = process;
    }

    public Task getTask() {
        return task;
    }

    public void setTask(Task task) {
        this.task = task;
    }
}

SDN訪問和持久化實體

SDN提供了一個Neo4jTemplate類陶夜,能用于實例化,可以直接使用或當(dāng)Spring初始化時用于應(yīng)用程序裆站。類似于Spring模板類JDBCTemplate条辟,它提供了很多其他的底層應(yīng)用方法用于操作、查詢以及獲得對節(jié)點和關(guān)系的訪問宏胯。


 @Autowired 
 private Neo4jTemplate neo4jTemplate;

 @Transactional 
 public void  saveTask(){
        Task task = new Task();
        task.setTaskName("測試任務(wù)");
        Task save = neo4jTemplate.save(task);
        Task load = neo4jTemplate.load(Task.class, save.getId());
        System.out.println(load.getTaskName());
 }

如上述表示羽嫡,通過@Autowired 注入該類,就可以調(diào)用起操作肩袍、查詢等方法厂僧,實現(xiàn)對數(shù)據(jù)的實例化。但是一般在的真正的業(yè)務(wù)代碼的實現(xiàn)中了牛,用于加載和保存實體一般是通過資源庫模式來實現(xiàn)(簡單來說颜屠,就是用一個知道如何翻譯域?qū)嶓w到或從數(shù)據(jù)倉庫格式替換合適的資源庫實現(xiàn))。
SDN資源庫在某一段時間是專門設(shè)置用于一個域類鹰祸,并針對對應(yīng)的域類提供整個范圍的默認操作甫窟。
SDN提供了Interface GraphRepository<T>接口,自己定義的接口繼承擴展GraphRepository蛙婴,它定義了域類可用的默認操作的最廣集合粗井。Java泛型的使用把他與對應(yīng)的域?qū)嶓w聯(lián)系起來。

  public interface TaskRepository extends GraphRepository<Task> {}

GraphRepository接口從實質(zhì)上鞏固的所有的其他接口,因此為Task定義了包括CRUD的操作浇衬、索引和遍歷懒构。該接口比Neo4jTemplate 類高一級,它也是提供許多樣板代碼的實現(xiàn)耘擂,但以更針對域的方式胆剧。

SDN注解查詢

SDN除了提供了一系列的接口查詢外维贺,還提供了更高級的注解查詢炼邀,使用注解@Query用于標識一個執(zhí)行的查詢漫雕。注解可以用于一個節(jié)點的實體的一個字段上性誉,或者知識庫接口中的方法上靶剑。當(dāng)一個節(jié)點實體上的字段被訪問或在一個知識庫接口上調(diào)用一個方式時群凶,查詢被執(zhí)行并且返回結(jié)果柠偶。

@Query注釋可以定義在你自己實現(xiàn)的特定的接口上户秤,下面定義了兩個接口 一個通過名字查詢?nèi)蝿?wù)螺捐,一個則是通過流程實例id查詢相關(guān)的任務(wù)颠悬。查詢可設(shè)置變量,順序默認為接口參數(shù)名字定血。

@Repository
public interface TaskRepository extends GraphRepository<Task> {

    @Query("MATCH (t:Task) WHERE t.taskName =~ ('(?i).*'+{taskName}+'.*') RETURN t")
    Collection<Task> findByNameContaining(@Param("taskName") String taskName);

    @Query("START p = node({id}) MATCH (p:Process)-[r:PROCESS_IN]->(t:Task) RETURN t;")
    Collection<Task> findByProcessId(@Param("id") Long id);
}

SDN也能理解相關(guān)的屬性定義赔癌,如果你想通過任務(wù)的名字查詢某個任務(wù),可以定義以下方法糠悼。這里應(yīng)用了屬性的第一部分届榄,如果這個屬性是基于這個任務(wù)類型的,就可以通過任務(wù)的名字進行搜索倔喂。但屬性必須是存在的铝条,不存在啟動會出錯。

@Repository
public interface TaskRepository extends GraphRepository<Task> {
    Task findByTaskName(@Param("taskName") String taskName);
}

如果你想有多個屬性并列查詢時席噩,你可以通過And 或者Or將兩個屬性聯(lián)系起來班缰,查詢,參數(shù)則按順序?qū)懭搿?/p>

@Repository
public interface TaskRepository extends GraphRepository<Task> {
    Task findByTaskNameAndId(String taskName,Long id);
}

SDN與Spring集成

SDN原來版本集成是通過配置文件來實現(xiàn)悼枢。后期版本通過實現(xiàn)Neo4jConfiguration類 進行注入配置

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末埠忘,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子馒索,更是在濱河造成了極大的恐慌莹妒,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绰上,死亡現(xiàn)場離奇詭異旨怠,居然都是意外死亡,警方通過查閱死者的電腦和手機蜈块,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進店門鉴腻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來迷扇,“玉大人,你說我怎么就攤上這事爽哎◎严” “怎么了?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵课锌,是天一觀的道長厨内。 經(jīng)常有香客問我,道長产镐,這世上最難降的妖魔是什么隘庄? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任踢步,我火速辦了婚禮癣亚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘获印。我一直安慰自己述雾,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布兼丰。 她就那樣靜靜地躺著玻孟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鳍征。 梳的紋絲不亂的頭發(fā)上黍翎,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天,我揣著相機與錄音艳丛,去河邊找鬼匣掸。 笑死,一個胖子當(dāng)著我的面吹牛氮双,可吹牛的內(nèi)容都是我干的碰酝。 我是一名探鬼主播,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼戴差,長吁一口氣:“原來是場噩夢啊……” “哼送爸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起暖释,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤袭厂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后球匕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體纹磺,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年谐丢,在試婚紗的時候發(fā)現(xiàn)自己被綠了爽航。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚓让。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖讥珍,靈堂內(nèi)的尸體忽然破棺而出历极,到底是詐尸還是另有隱情,我是刑警寧澤衷佃,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布趟卸,位于F島的核電站,受9級特大地震影響氏义,放射性物質(zhì)發(fā)生泄漏锄列。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一惯悠、第九天 我趴在偏房一處隱蔽的房頂上張望邻邮。 院中可真熱鬧,春花似錦克婶、人聲如沸筒严。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鸭蛙。三九已至,卻和暖如春筋岛,著一層夾襖步出監(jiān)牢的瞬間娶视,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工睁宰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留肪获,地道東北人。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓勋陪,卻偏偏與公主長得像贪磺,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子诅愚,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,922評論 2 361

推薦閱讀更多精彩內(nèi)容