目录

  • 前言
  • Caché SQL
    • 在哪里可以使用 Caché SQL
    • SQL 的对象扩展
  • 持久类的特殊选项
  • 持久类的 SQL 投影
  • 对象 IDs
    • 如何确定 ID
    • 访问 ID
  • 存储
    • 查看存储定义
    • 持久类使用的全局变量
    • 存储对象的默认结构
    • 注意点
  • 用于创建持久类和表的选项
  • 访问数据
  • 查看存储的数据
  • 存储 Caché SQL 的生成代码

前言

Caché 的一个关键特性是它结合了对象技术和 SQL。您可以为任何给定方案使用最方便的访问模式。
Caché 提供了有时称为对象数据库的东西:一个与面向对象编程语言相结合的数据库。因此,您可以编写灵活的代码来执行以下所有操作:

  • 通过 SQL 执行数据大容量插入。
  • 打开对象,对其进行修改并保存,从而在不使用 SQL 的情况下更改一个或多个表中的数据。
  • 创建并保存新对象,在不使用 SQL 的情况下向一个或多个表添加行。
  • 使用 SQL 从与给定条件匹配的记录中检索值,而不是循环访问大量对象。
  • 删除对象,从一个或多个表中删除记录,而不使用 SQL。

也就是说,您可以在任何给定时间选择适合您需求的访问模式。
在内部,所有访问都是通过直接全局访问完成的,您也可以在适当的时候以这种方式访问数据。(如果您有类定义,则不建议使用直接全局访问来更改数据)

Caché SQL

Caché提供了SQL的实现,称为Caché SQL
Caché SQL 支持完整的入门级 SQL-92 标准,但有一些例外和几个特殊扩展。Caché SQL 还支持索引、触发器、BLOB 和存储过程(这些是典型的 RDBMS 功能,但不是 SQL-92 标准的一部分)。

在哪里可以使用 Caché SQL

您可以在Routines和方法中使用 Caché SQL。若要在这些上下文中使用 SQL,可以使用以下的两种方式:

  • 嵌入式 SQL,如以下示例所示:
&sql(SELECT COUNT(*) INTO :myvar FROM Sample.Person)Write myvar

动态 SQL(%SQL.Statement 和%SQL.StatementResult 类),如下面的示例所示:

SET myquery = "SELECT TOP 5 Name,DOB FROM Sample.Person"SET tStatement = ##class(%SQL.Statement).%New()SET tStatus = tStatement.%Prepare(myquery)SET rset = tStatement.%Execute()//now use proprties of rset object

SQL 的对象扩展

为了便于在对象应用程序中使用 SQL,Caché 在 SQL 中包含了许多对象扩展。

箭头运算符
这些扩展中最有趣的扩展之一是能够使用引用(“–>”)运算符跟踪对象引用。例如,假设您有一个供应商引用其他两个类的类:联系和地区.您可以使用引用运算符引用相关类的属性:

SELECT ID,Name,ContactInfo->Name
FROM Vendor
WHERE Vendor->Region->Name = 'Antarctica'

当然,也可以使用 SQL JOIN 语法表示相同的查询。引用运算符语法的优点是它简洁明了,一目了然地易于理解。

持久类的特殊选项

Caché 中,所有持久性类都扩展了 %Library.Persistent(也称为 %Persistent)。此类为Caché中的 object-SQL 对应关系提供了大部分框架。在持久性类中,您有如下选项:

  • 用于打开、保存和删除对象的方法。
    打开持久性对象时,可以指定并发锁定的程度,因为持久性对象可能由多个用户或多个进程使用。
    当您打开对象实例并引用对象值属性时,系统也会自动打开该对象。此过程称为旋转(也称为延迟加载)。然后,您也可以使用该对象。例如:
 Set person=##class(Sample.Person).%OpenId(10)Set person.Name="Andrew Park"Set person.Address.City="Birmingham" Do person.%Save()

同样,当您保存对象时,系统也会自动保存其所有对象值属性。这被称为深度保存。有一个选项可以改为执行浅保存

  • 默认查询(扩展数据块查询),它是包含此类对象数据的 SQL 结果集。
    在此类(或其他类)中,可以定义其他查询;
  • 能够定义作为外键投影到 SQL 的类之间的关系。
    关系是一种特殊类型的对象值属性,它定义两个或多个对象实例如何相互关联。每个关系都是双面的:对于每个关系定义,都有一个相应的逆向关系来定义另一侧。Caché 自动强制实施数据的参照完整性,一端的任何操作在另一侧立即可见。关系会自动管理其内存中和磁盘上的行为。它们还提供了优于对象集合的缩放和并发性
  • 能够定义外键。实际上,添加外键以向现有应用程序添加参照完整性约束。对于新应用程序,定义关系会更简单。
  • 能够在这些类中定义索引。
    索引提供了一种机制,用于优化跨持久性类实例的搜索;它们定义了与类关联的常用请求数据的特定排序子集。它们在减少性能关键型搜索的开销方面非常有帮助。
    可以对属于其类的一个或多个属性对索引进行排序。这使您可以对结果返回的顺序进行大量特定的控制。
    此外,索引可以存储基于排序属性的查询经常请求的其他数据。通过将其他数据作为索引的一部分包括在内,可以大大提高使用该索引的查询的性能。当查询使用索引生成其结果集时,它可以在不访问主数据存储设施的情况下执行此操作。
  • 能够在这些类中定义触发器,以控制插入、修改或删除行时发生的情况。
  • 能够将方法和类查询投影为 SQL 存储过程。
  • 能够将投影微调为 SQL(例如,指定 SQL 查询中看到的表名和列名)。
  • 能够微调存储对象数据的全局变量的结构。

持久类的 SQL 投影

对于任何持久性类,该类的每个实例都可用作表中的一行,您可以通过 SQL 对其进行查询和操作。

由于继承不是关系模型的一部分,因此类编译器将持久性类的“扁平化”表示形式投影为关系表。下表列出了如何将某些各种对象元素投影到 SQL:

Object Concept SQL Concept
Package Schema
Class Table
Data type property (数据类型属性) Field
Embedded object Set of fields
List property List field
Array property Child table
Stream property BLOB
Index Index
Class method marked as stored procedure Stored procedure(存储过程)

投影表包含该类的所有相应字段,包括继承的字段。

对象 IDs

每个对象在其所属的每个范围内都有一个唯一的 ID。在大多数情况下,您可以使用此 ID 来处理对象。此 ID 是 %Persistent 类的以下常用方法的参数:

  • %DeleteId()
  • %ExistsId()
  • %OpenId()

如何确定 ID

Caché 会在您首次保存对象时分配ID值。任务是永久性的;您无法更改对象的 ID。删除或更改其他对象时,不会为对象分配新 ID。
任何 ID 在其范围内都是唯一的。
对象的 ID 按如下方式确定:

  • 对于大多数类,默认情况下,ID 是在保存该类的对象时按顺序分配的整数。
  • 对于在父子关系中用作子类的类,ID 的形成如下所示:
parentID||childID

其中 parentID是父对象的 ID,childID 是子对象在父子关系中未使用时将接收的 ID

  • 如果类的索引类型为 IdKey,并且索引位于特定属性上,则该属性值将用作 ID。
SKU-447

此外,属性值不能更改。

  • 如果类具有 IdKey 类型的索引,并且该索引位于多个属性上,则这些属性值将串联起来形成 ID。例如:
CATEGORY12||SUBCATEGORYA

访问 ID

若要访问对象的 ID 值,请使用对象从 %Persistent 继承的 %Id() 实例方法。
在 SQL 中,对象的 ID 值可用作名为 %Id 的伪字段。

存储

每个持久性类定义都包含描述如何将类属性映射到实际存储它们的全局变量的信息。类编译器为类生成此信息,并在您修改和重新编译时对其进行更新。

查看存储定义

查看此信息可能很有用,在极少数情况下,您可能希望更改某些详细信息(非常仔细)。对于持久性类,Studio 会在类定义中显示如下所示的内容:

<Storage name="Default">
<Data name="PersonDefaultData"><Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>Name</Value>
</Value>
<Value name="3">
<Value>SSN</Value>
</Value>
<Value name="4">
<Value>DOB</Value>
</Value>
...
</Storage>

持久类使用的全局变量

存储定义包括几个元素,这些元素指定存储数据的全局变量:

<DataLocation>^Sample.PersonD</DataLocation>
<IdLocation>^Sample.PersonD</IdLocation>
<IndexLocation>^Sample.PersonI</IndexLocation>
...
<StreamLocation>^Sample.PersonS</StreamLocation>

默认情况下,使用默认存储:

  • 类数据存储在类的数据全局中。其名称以完整的类名(包括包名)开头。名称后面附加“D”。例如:Sample.PersonD
  • 索引数据存储在类的索引全局中。它的名称以类名开头,以“I”结尾。例如:Sample.PersonI
  • 任何已保存的流属性都存储在类的流全局中。它的名称以类名开头,以“S”结尾。例如:Sample.PersonS

注意

如果完整的类名很长,系统会自动使用类名的哈希形式。因此,当您查看存储定义时,有时可能会看到全局名称,例如 ^package1.pC347.VeryLongCla4F4AD。如果出于任何原因计划直接使用某个类的数据全局,请确保检查存储定义,以便知道全局变量的实际名称。

存储对象的默认结构

对于典型类,大多数数据都包含在数据全局中,其中包括如下节点:

节点 节点内容
^full_class_name(“id”) 其中 full_class_name 是包含包的完整类名,如有必要,将长度保持在 31 个字符以求散列。此外,id 是“对象 ID”中所述的对象 ID。 $ListBuild返回的格式列表。在此列表中,存储的属性按存储定义中<值>元素的 name 属性给出的顺序列出。根据定义,不存储瞬态属性。流属性存储在类的流全局中

注意点

请注意以下几点:

  • 切勿为已存储数据的类重新定义或删除存储。如果这样做,则必须手动重新创建存储,因为在下次编译类时创建的新默认存储可能与类所需的存储不匹配。
  • 在开发过程中,您可能希望重置类的存储定义。如果同时删除数据,然后重新加载或重新生成数据,则可以执行此操作。
  • 默认情况下,当您在开发过程中添加和删除属性时,系统会通过称为架构演变的过程自动更新存储定义。
    例外情况是,如果对<Type>元素使用非默认存储类。默认值为 %Library.CacheStorage;如果不使用此存储类,Caché 不会更新存储定义。另一个常用选项是 %Library.CacheSQLStorage,它主要用于支持在 Caché 提供类之前编写的应用程序。

用于创建持久类和表的选项

若要创建持久性类及其相应的SQL表,可以执行以下任一操作:

  • 使用 Studio 定义基于 %Persistent 的类。编译类时,系统将创建表。
  • 在管理门户中,可以使用数据迁移向导,该向导读取外部表,提示你输入一些详细信息,生成基于 %Persistent 的类,然后将记录加载到相应的 SQL 表中。
    您可以稍后再次运行该向导以加载更多记录,而无需重新定义该类。
  • 在管理门户中,可以使用链接表向导,该向导读取外部表,提示你输入一些详细信息,并生成链接到外部表的类。该类在运行时从外部表中检索数据。
    这是一个特例,本书不作进一步讨论。
  • 在管理门户中,可以使用 FileMan 向导,该向导读取 FileMan 文件并创建类。
    在 Caché SQL 中,使用 CREATE TABLE 或其他 DDL 语句。这还会创建一个类。
  • 在终端(或代码)中,使用 %SQL.Util.Procedures 中的 CSVTOCLASS() 方法。

访问数据

若要访问、修改和删除与持久性类关联的数据,您的代码可以执行以下任何或所有操作:

  • 打开持久性类的实例,修改它们,然后保存它们。
  • 删除持久性类的实例。
  • 使用嵌入式 SQL
  • 使用动态 SQL(SQL 语句和结果集接口)。
  • 使用低级命令和函数进行直接全局访问。请注意,除了检索存储的值之外,不建议使用此技术,因为它会绕过由对象和 SQL 接口定义的逻辑。

Caché SQL 适用于以下情况:

  • 您最初不知道要打开的实例的 ID,而是会根据输入条件选择一个或多个实例。
  • 您希望执行批量加载或进行批量更改。
  • 您希望查看数据,但不希望打开对象实例。
    (但请注意,使用对象访问时,可以控制并发锁定的程度。如果您知道不打算更改数据,则可以使用最小并发锁定)
  • 您精通 SQL。

对象访问适用于以下情况:

  • 您正在创建一个新对象。
  • 您知道要打开的实例的 ID。
  • 您会发现设置属性值比使用 SQL 更直观。

查看存储的数据

本节演示,对于任何持久性对象,相同的值通过对象访问SQL 访问和直接全局访问可见。
在工作室中,如果我们查看样本.人类,我们看到以下属性定义:

/// Person's name.
Property Name As %String(POPSPEC = "Name()") [ Required ];.../// Person's age.<br>
/// This is a calculated field whose value is derived from <property>DOB</property>.
Property Age As %Integer [ details removed for this example ]; /// Person's Date of Birth.
Property DOB As %Date(POPSPEC = "Date()");

在终端中,我们可以打开一个存储对象并写入其属性值:

SAMPLES>set person=##class(Sample.Person).%OpenId(1)SAMPLES>w person.Name
Newton,Dave R.
SAMPLES>w person.Age
14
SAMPLES>w person.DOB
58153

请注意,在这里我们看到DOB属性的文字存储值。我们可以调用一个方法来返回此属性的显示值:

SAMPLES>write person.DOBLogicalToDisplay(person.DOB)
03/20/2000

在管理门户中,我们可以浏览此类的存储数据,如下所示:

请注意,在本例中,我们将看到DOB属性的显示值。(在门户中,还有另一个用于执行查询的选项,使用该选项可以控制对结果是使用逻辑模式还是显示模式。
在门户中,我们还可以浏览包含此类数据的全局变量:

或者,在终端中,我们可以写入包含此实例的全局节点的值:

zw ^Sample.PersonD("1")
^Sample.PersonD(1)=$lb("","Newton,Dave R.","384-10-6538",58153,$lb("6977 First Street","Pueblo","AK",63163),
$lb("9984 Second Blvd","Washington","MN",42829),"",$lb("Red"))

存储 Caché SQL 的生成代码

对于 Caché SQL(用作嵌入式 SQL 时除外),系统会生成可重用的代码来访问数据。
首次执行 SQL 语句时,Caché 会优化查询并生成和存储检索数据的代码。它将代码与优化的查询文本一起存储在查询缓存中。请注意,此缓存是代码缓存,而不是数据缓存。
稍后,当您执行 SQL 语句时,Caché 会对其进行优化,然后将该查询的文本与查询缓存中的项进行比较。如果 Caché 找到与给定查询匹配的存储查询(除了空格等细微差异),它将使用为该查询存储的代码。
您可以查看查询缓存并删除其中的任何项目。

第6集丨Persistent Objects 和 Caché SQL相关推荐

  1. eXpress Persistent Objects (XPO)入门:数据查询

    DevExpress旗下的 eXpress Persistent Objects(XPO) 是专为.NET平台提供的高级对象关系映射工具,旨在让开发人员在更高的抽象层级管理他们的数据.接下来小编将为大 ...

  2. 第1集丨IRIS 编程简介

    目录 何为 IRIS 编程 Routines 类(Classes) 全局变量(Globals ) 访问数据的方法 使用全局变量意义 Caché SQL 宏(Macros) 包含文件(Include F ...

  3. 学习:双机热备、集群、负载均衡、SQL故障转移群集简单理解(转)

    双机热备.集群.负载均衡.SQL故障转移群集简单理解平常,大家常提到几个技术名词:双机热备.集群.负载均衡.SQL故障转移群集.这里,就我的理解,和大家简单探讨下,有不足或错误之处还请各位指出! 这些 ...

  4. Caché SQL 高性能优化

    Caché SQL 高性能优化 第一章 SQL性能优化简介☆☆☆ 第二章 定义和构建索引(一)☆☆☆☆☆ 第二章 定义和构建索引(二)☆☆☆☆☆ 第二章 定义和构建索引(三)☆☆☆☆☆ 第二章 定义和 ...

  5. mybatis 不确定结果集集_集集丨与小直男的日常(三)

    2019.10.9 九月十一•周三 日●常 集集 珍惜当下 珍惜对的人 不属于你的 就学会放手吧 耽 电影 剧集 美 与小直男的日常 Day2-Day7(三) 刚要提起"笔",一下 ...

  6. 设备产线运维合集丨图扑数字孪生流水线,提升产品装配自动化效率

    前言 图扑软件基于 HTML5(Canvas/WebGL/WebVR)标准的 Web 技术,满足了工业物联网跨平台云端化部署实施的需求,以低代码的形式自由构建三维数字孪生.大屏可视化.工业组态等等.从 ...

  7. 第17集丨如何为成功“保鲜”

    目录 主一之功 天理是什么? 程朱定义 阳明定义 笔者理解 心学是要让人无情无欲吗? 好色 好名.好利 节欲 要想成功就必须脸厚心黑吗? 企业失败原因 小日本盗取 主一之功 陆澄问:"主一之 ...

  8. 春节文案新年文案合集丨扩充运营素材库必备

    一年当中最重要的节日,农历新年就要到了! 运营小伙伴们,小新在这里,提前给大家说声:新年好~ 放假前最后一篇推文准备好了吗? 今天咱们整篇实用的:春节文案大合集! 足足25条,不管你运营的是什么行业类 ...

  9. 码蹄集丨三角形的个数

    题目来源:码蹄集 题意第一行就是输入有几个图形,接下来第二行的2意思就是对一个三角形每条边做2等分,第三行的3就是对一个三角形的每条边做三等分.输出就是做了等分后的三角形图案中,一共有多少个三角形. ...

  10. 第10集丨龙场悟道:阳明心学的诞生

    浓墨般的黑暗中,深山岩洞一灯如豆,犹如万古长夜中,我心本具的一点灵明.风吹过,烛光微微颤动,仿佛随时都会熄灭.王守仁像一具雕像一样坐在石棺中,看见往事一幕幕从心头闪过. 那一年在蔽月山房,有个11岁的 ...

最新文章

  1. Doxygen生成代码关系调用图
  2. Modbus通讯错误检测方法
  3. 基于Verilog的按键控制LED灯
  4. JAVA面试常考系列十
  5. Ubuntu通过可视化界面配置 查找IP地址不存在的解决办法
  6. 【codevs2822】爱在心中 tarjan 缩点+理解
  7. mysql改utf8mb4后速度慢_更改MySQL数据库的编码为utf8mb4
  8. 粉丝大失所望,罗永浩回应:做主播赚的不是脏钱
  9. 箱线图怎么看_K线的48种不同类型全解(建议收藏),教你怎么看懂K线图
  10. android av和hdmi输出切换代码,AV转HDMI转换器有用吗?
  11. 调戏木马病毒的正确姿势——上
  12. PWM整流器仿真。 在simulink中搭建了PWM整流器,采用电压电流双闭环控制,实现了网侧电压与电流同相位,单位功率因数运行
  13. SMT贴片加工回流焊接出现的问题和解决对策
  14. 【田间连着车间、佘太酒业这十年!
  15. Android源码阅读记录
  16. c/c++通过域名解析ip地址
  17. 【常用工具类】EasyExcel
  18. 误删除系统libselinux.so.1之后
  19. 对YY/T 0287-2017 医疗器械 质量管理体系的一些学习
  20. 记一次内网jenkins自动发布血泪史

热门文章

  1. 02-02 逐帧动画、多组动画案例 实现小人跑步效果
  2. 图像处理之matlab中fspecial函数用法详解
  3. 中职微型计算机说课,微型计算机原理说课.ppt
  4. win10编译OpenCV4Android系列2-编译OpenCV4.5.2+opencv_contrib
  5. COMSOL Multiphysics 多物理场仿真学习小记
  6. 杰里之 2M 的 SDK 开蓝牙一拖二出现奇怪的问题【篇】
  7. python制作指定区域截图工具_用python实现选择截图区域
  8. PR转场预设 放大特效带有重影效果的PR视频转场预设
  9. 云课堂让职业院校云计算教学更简单
  10. ERP管理web后台_数字化、智能化工厂管理系统原型、erp生产管理、仓库管理、采购管理、设备能源管理、计划管理、数字化工厂erp管理系统、生产计划、采购计划、用料请领、产品bom、工序管理、车间设备