OrientDB 教程

OrientDB 主页 OrientDB 概述 OrientDB 下载安装和环境配置 OrientDB 基本概念 OrientDB 数据类型 OrientDB 控制台模式

OrientDB 数据库命令

OrientDB 创建数据库 OrientDB 更改数据库 OrientDB 备份数据库 OrientDB 恢复数据库 OrientDB 连接数据库 OrientDB 断开数据库 OrientDB 信息数据库 OrientDB 列出数据库 OrientDB 冻结数据库 OrientDB 释放数据库 OrientDB 配置数据库 OrientDB 导出数据库 OrientDB 导入数据库 OrientDB 提交数据库 OrientDB 回滚数据库 OrientDB 优化数据库 OrientDB 删除数据库

OrientDB 记录命令

OrientDB 插入记录 OrientDB 显示记录 OrientDB 加载记录 OrientDB 重新加载记录 OrientDB 导出记录 OrientDB 更新记录 OrientDB 截断记录 OrientDB 删除记录

OrientDB 类命令

OrientDB 创建类 OrientDB 更改类 OrientDB 截断类 OrientDB 删除类

OrientDB 集群命令

OrientDB 创建集群 OrientDB 更改群集 OrientDB 截断群集 OrientDB 删除群集

OrientDB 属性命令

OrientDB 创建属性 OrientDB 更改属性 OrientDB 删除属性

OrientDB 顶点命令

OrientDB 创建顶点 OrientDB 移动顶点 OrientDB 删除顶点

OrientDB 边命令

OrientDB 创建边 OrientDB 更新边 OrientDB 删除边

OrientDB高级概念

OrientDB 函数 OrientDB 序列 OrientDB 索引 OrientDB 事务 OrientDB 钩子 OrientDB 缓存 OrientDB 日志 OrientDB 性能调优 OrientDB 升级 OrientDB 安全 OrientDB Studio

OrientDB 接口

OrientDB Java 接口 OrientDB Python 接口

OrientDB 有用资源

OrientDB 快速指南 OrientDB 有用资源 OrientDB 讨论


OrientDB - Hooks

OrientDB Hooks(钩子) 只不过是数据库术语中的触发器,可在用户应用程序中的每个 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

现在尝试通过创建新的 Invoice 文档来使用该钩子。

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

如果此命令执行成功,您将获得以下输出。

Invoice created: 100

文档级钩子

您可以仅针对一个或多个文档定义特殊操作。为此,允许您的类扩展 OTriggered 类。

例如,让我们针对现有的 Profile 类执行一个触发器(作为 Javascript 函数),针对所有具有属性 account = 'Premium' 的文档。将调用该触发器以防止删除文档。

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

然后尝试删除"Premium"帐户来测试该钩子。

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 Hooks

OrientDB Hooks(触发器)的一个常见用例是管理任何或所有类的创建和更新日期。例如,您可以在创建记录时设置 CreatedDate 字段,并在更新记录时设置 UpdatedDate 字段,并且以一种在数据库层实现一次逻辑的方式执行此操作,而不必在应用程序层再次担心它。

在创建之前,您必须通过访问以下链接下载 orientdb-core.jar 文件 下载 OrientDB 核心。然后将这个 jar 文件复制到你想要存储 Java 源文件的文件夹中。

创建 Hook 文件

创建一个名为 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 和 UpdateDate,每次更新记录时仅设置 UpdateDate。

编译 Java Hooks

使用以下命令编译 Java 代码。注意:将下载的 jar 文件和这些 Java 文件保存到同一文件夹中。

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

将编译后的代码移动到 OrientDB 服务器可以找到它的位置

您需要将完成的 .jar 文件复制到 OrientDB 服务器将查找它们的目录中。这意味着 OrientDB Server 根目录下的'./lib'文件夹将如下所示 −

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

在 OrientDB Server 配置文件中启用测试钩子

编辑 $ORIENTDB_HOME/config/orientdb-server-config.xml 并在文件末尾附近添加以下部分。

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

重新启动 OrientDB 服务器

重新启动 OrientDB 服务器后,您在 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 服务器配置文件中启用 Real Hook

编辑 $ORIENTDB_HOME/config/orientdb-server-config.xml 并按如下方式更改 hooks 部分 −

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

重启 OrientDB 服务器

创建一个以字母'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 专家,希望本教程中包含的信息能让您领先一步并让您熟悉该技术,使您能够在需要时成功创建数据库触发器。