OrientDB掛鉤

2018-12-24 15:44 更新

OrientDBHooks只是數(shù)據(jù)庫(kù)術(shù)語(yǔ)中的觸發(fā)器,它們?cè)谟脩魬?yīng)用程序中的每個(gè)CRUD操作之前和之后啟用內(nèi)部事件。您可以使用鉤子編寫(xiě)自定義驗(yàn)證規(guī)則,強(qiáng)制實(shí)施安全性,或安排外部事件,例如根據(jù)關(guān)系型DBMS進(jìn)行復(fù)制。

OrientDB支持兩種鉤子:

動(dòng)態(tài)Hook-觸發(fā)器,可以在類級(jí)別和/或文檔級(jí)別構(gòu)建。
Java(Native)Hook-觸發(fā)器,可以使用Java類構(gòu)建。
動(dòng)態(tài)鉤子
動(dòng)態(tài)鉤子比Java鉤子更靈活,因?yàn)樗鼈兛梢栽谶\(yùn)行時(shí)更改,并且如果需要可以運(yùn)行每個(gè)文檔,但是比Java鉤子慢。
要對(duì)你的文檔執(zhí)行鉤子,首先讓你的類擴(kuò)展TOTriggeredbase類。稍后,為感興趣的事件定義自定義屬性。以下是可用的事件。
onBeforeCreate-在創(chuàng)建新文檔之前調(diào)用。
onAfterCreate-在創(chuàng)建新文檔后調(diào)用。
onBeforeRead-調(diào)用文檔。
onAfterRead-調(diào)用文檔。
onBeforeUpdate-調(diào)用文檔之前調(diào)用。
onAfterUpdate - 更新文檔后調(diào)用。
onBeforeDelete-在刪除文檔之前調(diào)用。
onAfterDelete-在刪除文檔后調(diào)用。
動(dòng)態(tài)掛鉤可以調(diào)用:
函數(shù),用SQL,Javascript或OrientDB和JVM支持的任何語(yǔ)言編寫(xiě)。
Java靜態(tài)方法。
類級(jí)別鉤子
為與類相關(guān)的所有文檔定義類級(jí)別鉤子。以下是設(shè)置在類級(jí)別處對(duì)Invoice文檔執(zhí)行操作的掛鉤的示例。

CREATE CLASS Invoice EXTENDS OTriggered 
ALTER CLASS Invoice CUSTOM onAfterCreate = invoiceCreated 

讓我們?cè)贘avascript中創(chuàng)建invoiceCreated函數(shù),在服務(wù)器控制臺(tái)中打印創(chuàng)建的發(fā)票號(hào)。

CREATE FUNCTION invoiceCreated "print('
Invoice created: ' + doc.field ('number'));"
LANGUAGE Javascript

現(xiàn)在通過(guò)創(chuàng)建一個(gè)新的Invoice文檔來(lái)嘗試掛鉤。

INSERT INTO Invoice CONTENT {number: 100, notes: 'This is a test}

如果成功執(zhí)行這個(gè)命令,你會(huì)得到下面的輸出。

Invoice created: 100

文檔級(jí)掛鉤

只能針對(duì)一個(gè)或多個(gè)文檔定義一個(gè)特殊操作。要做到這一點(diǎn),讓你的類來(lái)擴(kuò)展OTriggered類。

例如,讓我們執(zhí)行一個(gè)觸發(fā),例如JavaScript功能,針對(duì)存在的Profile類,所有的財(cái)產(chǎn)賬戶='高級(jí)'的文件。觸發(fā)器將被調(diào)用,以防止文件刪除。

ALTER CLASS Profile SUPERCLASS OTriggered UPDATE Profile 
SET onBeforeDelete = 'preventDeletion' WHERE account = 'Premium' 

讓我們創(chuàng)建preventDeletion()JavaScript函數(shù)。

CREATE FUNCTION preventDeletion "throw new java.lang.RuntimeException('Cannot 
delete Premium profile ' + doc)" LANGUAGE Javascript

然后通過(guò)嘗試刪除Premium帳戶來(lái)測(cè)試掛鉤。

DELETE FROM #12:1 
java.lang.RuntimeException: Cannot delete Premium profile
profile#12:1{onBeforeDelete:preventDeletion,account:Premium,name:Jill} v-1 
(<Unknown source>#2) in <Unknown source> at line number 2

JAVA鉤

OrientDB Hooks(觸發(fā)器)的一個(gè)常見(jiàn)用例是管理任何或所有類的創(chuàng)建和更新日期。 例如,可以在創(chuàng)建記錄時(shí)設(shè)置aCreatedDatefield,并在更新記錄時(shí)設(shè)置anUpdatedDatefield,并在數(shù)據(jù)庫(kù)層實(shí)現(xiàn)邏輯一次,而不必在應(yīng)用程序?qū)釉俅螕?dān)心它。
在創(chuàng)建之前,您必須通過(guò)訪問(wèn)以下鏈接下載OrientDB核心:下載orientdb-core.jarfile。 然后將該jar文件復(fù)制到要存儲(chǔ)Java源文件的文件夾中。
創(chuàng)建鉤子文件
創(chuàng)建一個(gè)名為HookTest.java的Java文件,它將使用Java語(yǔ)言測(cè)試Hook機(jī)制。

import java.io.BufferedReader; 
import java.io.FileNotFoundException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.StringReader; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.concurrent.locks.ReentrantLock; 
import com.orientechnologies.orient.core.hook.ODocumentHookAbstract; 
import com.orientechnologies.orient.core.hook.ORecordHook; 
import com.orientechnologies.orient.core.hook.ORecordHookAbstract; 
import com.orientechnologies.orient.core.db.ODatabaseLifecycleListener; 
import com.orientechnologies.orient.core.db.ODatabase; 
import com.orientechnologies.orient.core.record.ORecord; 
import com.orientechnologies.orient.core.record.impl.ODocument;
  
public class HookTest extends ODocumentHookAbstract implements ORecordHook { 
   public HookTest() {
  
   }
  
   @Override 
   public DISTRIBUTED_EXECUTION_MODE getDistributedExecutionMode() { 
      return DISTRIBUTED_EXECUTION_MODE.BOTH; 
   } 
   public RESULT onRecordBeforeCreate( ODocument iDocument ) { 
      System.out.println("Ran create hook"); 
      return ORecordHook.RESULT.RECORD_NOT_CHANGED; 
   } 
   public RESULT onRecordBeforeUpdate( ODocument iDocument ) { 
      System.out.println("Ran update hook"); 
      return ORecordHook.RESULT.RECORD_NOT_CHANGED;  
   }  
} 

上面的示例代碼打印每次創(chuàng)建或更新類的創(chuàng)紀(jì)錄的時(shí)間適當(dāng)?shù)淖⑨尅?

讓我們添加更多的鉤子文件setCreatedUpdatedDates.java如下-

import java.io.BufferedReader; 
import java.io.FileNotFoundException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.StringReader; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.concurrent.locks.ReentrantLock; 
import com.orientechnologies.orient.core.hook.ODocumentHookAbstract; 
import com.orientechnologies.orient.core.hook.ORecordHook; 
import com.orientechnologies.orient.core.hook.ORecordHookAbstract; 
import com.orientechnologies.orient.core.db.ODatabaseLifecycleListener; 
import com.orientechnologies.orient.core.db.ODatabase; 
import com.orientechnologies.orient.core.record.ORecord; 
import com.orientechnologies.orient.core.record.impl.ODocument; 
 
public class setCreatedUpdatedDates extends ODocumentHookAbstract implements ORecordHook { 
   public setCreatedUpdatedDates() { 
   
   }
   
   @Override 
   public DISTRIBUTED_EXECUTION_MODE getDistributedExecutionMode() { 
      return DISTRIBUTED_EXECUTION_MODE.BOTH; 
   } 
   public RESULT onRecordBeforeCreate( ODocument iDocument ) { 
      if ((iDocument.getClassName().charAt(0) == 't') || (iDocument.getClassName().charAt(0)=='r')) { 
         iDocument.field("CreatedDate", System.currentTimeMillis() / 1000l); 
         iDocument.field("UpdatedDate", System.currentTimeMillis() / 1000l); 
         return ORecordHook.RESULT.RECORD_CHANGED; 
      } else { 
         return ORecordHook.RESULT.RECORD_NOT_CHANGED; 
      } 
   } 
   
   public RESULT onRecordBeforeUpdate( ODocument iDocument ) { 
      if ((iDocument.getClassName().charAt(0) == 't') || (iDocument.getClassName().charAt(0)=='r')) { 
         iDocument.field("UpdatedDate", System.currentTimeMillis() / 1000l); 
         return ORecordHook.RESULT.RECORD_CHANGED; 
      } else { 
         return ORecordHook.RESULT.RECORD_NOT_CHANGED; 
      } 
   }  
}

上面的代碼所做的是尋找以字母'r'或't'開(kāi)頭的任何類別,并且在創(chuàng)建記錄時(shí)設(shè)置CreatedDate和UpdatedDate,并在每次記錄更新時(shí)設(shè)置為UpdatedDate。

編譯Java鉤子

使用以下命令編譯Java代碼。

注意:將下載的jar文件和這些Java文件保存在同一個(gè)文件夾中。

$ jar cf hooks-1.0-SNAPSHOT.jar *.java

將編譯的代碼移動(dòng)到OrientDB服務(wù)器可以找到它
您需要將完成的.jar文件復(fù)制到您的OrientDB服務(wù)器將查找它們的目錄。 這意味著您的OrientDB服務(wù)器根目錄下的“./lib”文件夾將如下所示:

$ cp hooks-1.0-SNAPSHOT.jar "$ORIENTDB_HOME/lib"

在OrientDB服務(wù)器配置文件中啟用測(cè)試掛接
編輯$ ORIENTDB_HOME / config / orientdb-server-config.xmland在文件末尾添加以下部分。

   <hooks> 
      <hook class = "HookTest" position = "REGULAR"/> 
   </hooks> 
   ... 
</orient-server>

重新啟動(dòng)OrientDB服務(wù)器
一旦您重新啟動(dòng)OrientDB服務(wù)器,您定義的鉤子inorientdb-server-config.xml現(xiàn)在是活動(dòng)的。 啟動(dòng)OrientDB控制臺(tái),將其連接到數(shù)據(jù)庫(kù),然后運(yùn)行以下命令 -

INSERT INTO V SET ID = 1;

如果成功執(zhí)行這個(gè)命令,你會(huì)得到下面的輸出。

Ran create hook 

現(xiàn)在運(yùn)行以下命令:

UPDATE V SET ID = 2 WHERE ID = 1; 

如果成功執(zhí)行這個(gè)命令,你會(huì)得到下面的輸出。

Ran update hook

在OrientDB服務(wù)器配置文件中啟用Real Hook
編輯$ ORIENTDB_HOME / config / orientdb-server-config.xmland更改鉤子部分如下:

   <hooks> 
      <hook class="setCreatedUpdatedDates" position="REGULAR"/> 
   </hooks> 
   ... 
</orient-server>

重新啟動(dòng)服務(wù)器OrientDB

創(chuàng)建以字母“R”“T”開(kāi)頭的新類。

CREATE CLASS tTest EXTENDS V;

現(xiàn)在,插入一條記錄。

INSERT INTO tTest SET ID = 1 
SELECT FROM tTest 

如果成功執(zhí)行這個(gè)命令,你會(huì)得到下面的輸出。

----+-----+------+----+-----------+----------- 
#   |@RID |@CLASS|ID  |CreatedDate|UpdatedDate 
----+-----+------+----+-----------+----------- 
0   |#19:0|tTest |1   |1427597275 |1427597275 
----+-----+------+----+-----------+-----------

即使您沒(méi)有指定要為CreatedDate和UpdatedDate設(shè)置的值,OrientDB也會(huì)為您自動(dòng)設(shè)置這些字段。
接下來(lái),您需要使用以下命令更新記錄 

UPDATE tTest SET ID = 2 WHERE ID = 1; 
SELECT FROM tTest; 

如果成功執(zhí)行這個(gè)命令,你會(huì)得到下面的輸出:

----+-----+------+----+-----------+----------- 
#   |@RID |@CLASS|ID  |CreatedDate|UpdatedDate 
----+-----+------+----+-----------+----------- 
0   |#19:0|tTest |2   |1427597275 |1427597306 
----+-----+------+----+-----------+----------- 

你可以看到OrientDB改變了UpUpdatedDate,但是讓CreatedDateremain保持不變。
OrientDB Java Hooks可以是一個(gè)非常有價(jià)值的工具,幫助自動(dòng)化您在應(yīng)用程序代碼中必須做的工作。 由于許多DBA并不總是Java專家,希望本教程中包含的信息將為您提供一個(gè)良好的開(kāi)端,使您感到舒適的技術(shù),使您能夠根據(jù)需要成功創(chuàng)建數(shù)據(jù)庫(kù)觸發(fā)器。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)