📅  最后修改于: 2020-11-26 05:39:09             🧑  作者: Mango
OrientDB Hook只是数据库术语中的触发器,这些触发器在用户应用程序中的每个CRUD操作之前和之后启用内部事件。您可以使用挂钩来编写自定义验证规则,强制执行安全性或安排外部事件,例如根据关系DBMS进行复制。
OrientDB支持两种钩子-
动态挂钩-触发器,可以在类级别和/或文档级别构建。
Java(本机)挂钩-触发器,可以使用Java类构建。
动态挂钩比Java挂钩更灵活,因为动态挂钩可以在运行时进行更改,并且可以根据需要在每个文档中运行,但是比Java挂钩要慢。
要对文档执行挂钩,请首先允许您的类扩展OTriggered基类。以后,为感兴趣的事件定义一个自定义属性。以下是可用的事件。
onBeforeCreate-在创建新文档之前调用。
onAfterCreate-创建新文档后调用。
onBeforeRead-在阅读文档之前调用。
onAfterRead-阅读文档后调用。
onBeforeUpdate-在更新文档之前调用。
onAfterUpdate-更新文档后调用。
onBeforeDelete-在删除文档之前调用。
onAfterDelete-删除文档后调用。
动态挂钩可以调用-
用SQL,Javascript或OrientDB和JVM支持的任何语言编写的函数。
Java静态方法。
为所有与类有关的文档定义了类级挂钩。下面是一个示例,该示例设置了一个在类级别上针对发票文档进行操作的挂钩。
CREATE CLASS Invoice EXTENDS OTriggered
ALTER CLASS Invoice CUSTOM onAfterCreate = invoiceCreated
让我们创建用Javascript创建的invoiceCreated函数,该函数在服务器控制台中打印创建的发票编号。
CREATE FUNCTION invoiceCreated "print('\\nInvoice created: ' + doc.field ('number'));"
LANGUAGE Javascript
现在,通过创建新的发票文档来尝试执行该操作。
INSERT INTO Invoice CONTENT {number: 100, notes: 'This is a test}
如果此命令执行成功,您将获得以下输出。
Invoice created: 100
您只能针对一个或多个文档定义特殊操作。为此,请允许您的类扩展OTriggered类。
例如,让我们针对一个存在的Profile类,对属性account =’Premium’的所有文档执行触发器,作为Javascript函数。将调用该触发器以防止删除文档。
ALTER CLASS Profile SUPERCLASS OTriggered UPDATE Profile
SET onBeforeDelete = 'preventDeletion' WHERE account = 'Premium'
让我们创建preventDeletion() Javascript函数。
CREATE FUNCTION preventDeletion "throw new java.lang.RuntimeException('Cannot
delete Premium profile ' + doc)" LANGUAGE Javascript
然后通过尝试删除“高级”帐户来测试该挂钩。
DELETE FROM #12:1
java.lang.RuntimeException: Cannot delete Premium profile
profile#12:1{onBeforeDelete:preventDeletion,account:Premium,name:Jill} v-1
(#2) in at line number 2
OrientDB Hooks(触发器)的一种常见用例是管理任何或所有类的创建和更新日期。例如,您可以在创建记录时设置一个CreatedDate字段,并在记录更新时设置一个UpdatedDate字段,并以在数据库层一次实现逻辑而不必再担心的方式进行设置应用层。
在创建之前,您必须通过访问以下链接下载OrientDB core来下载orientdb-core.jar文件。然后,将该jar文件复制到要存储Java源文件的文件夹中。
创建一个名为HookTest.java的Java文件,该文件将使用Java语言测试Hook机制。
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;
}
}
每次创建或更新该类的记录时,以上示例代码都会打印相应的注释。
让我们再添加一个挂钩文件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 ‘开头并在创建记录时设置CreatedDate和UpdatedDate的任何类,并在每次记录更新时仅设置UpdatedDate的类。
通过使用以下命令来编译Java代码。注意:将下载的jar文件和这些Java文件保存在同一文件夹中。
$ jar cf hooks-1.0-SNAPSHOT.jar *.java
您需要将完成的.jar文件复制到OrientDB服务器将在其中查找它们的目录。这意味着OrientDB Server根目录下的’ ./lib ‘文件夹将如下所示-
$ cp hooks-1.0-SNAPSHOT.jar "$ORIENTDB_HOME/lib"
编辑$ ORIENTDB_HOME / config / orientdb-server-config.xml并在文件末尾附近添加以下部分。
...
重新启动OrientDB Server后,您在orientdb-server-config.xml中定义的挂钩现在处于活动状态。启动OrientDB控制台,将其连接到数据库,然后运行以下命令-
INSERT INTO V SET ID = 1;
如果此命令执行成功,您将获得以下输出。
Ran create hook
现在运行以下命令-
UPDATE V SET ID = 2 WHERE ID = 1;
如果此命令执行成功,您将获得以下输出。
Ran update hook
编辑$ ORIENTDB_HOME / config / orientdb-server-config.xml并更改hooks部分,如下所示-
...
创建一个以字母“ r ”或“ t ”开头的新类-
CREATE CLASS tTest EXTENDS V;
现在插入一条记录-
INSERT INTO tTest SET ID = 1
SELECT FROM tTest
如果此命令执行成功,您将获得以下输出。
----+-----+------+----+-----------+-----------
# |@RID |@CLASS|ID |CreatedDate|UpdatedDate
----+-----+------+----+-----------+-----------
0 |#19:0|tTest |1 |1427597275 |1427597275
----+-----+------+----+-----------+-----------
即使您没有指定要为CreatedDate和UpdatedDate设置的值,OrientDB也会自动为您设置这些字段。
接下来,您需要使用以下命令更新记录-
UPDATE tTest SET ID = 2 WHERE ID = 1;
SELECT FROM tTest;
如果此命令执行成功,您将获得以下输出。
----+-----+------+----+-----------+-----------
# |@RID |@CLASS|ID |CreatedDate|UpdatedDate
----+-----+------+----+-----------+-----------
0 |#19:0|tTest |2 |1427597275 |1427597306
----+-----+------+----+-----------+-----------
您可以看到OrientDB更改了UpdatedDate,但让CreatedDate保持不变。
OrientDB Java Hooks是一个非常有价值的工具,可以帮助您自动执行否则需要在应用程序代码中完成的工作。由于许多DBA并不总是Java专家,因此希望本教程中包含的信息能使您早日入门,并使您对技术感到满意,从而使您能够根据需要成功创建数据库触发器。