目录
本章讨论类定义类 (class definition classes
),这是一组持久性类,提供对所有类定义的对象和 SQL 访问。
%Dictionary.ClassDefinition
、%Dictionary.xxxDefinition- %Dictionary.CompiledClass
一、类定义类简介
类定义类 提供对 Caché
统一字典的对象和 SQL
访问。使用这些类,可以以编程方式检查类定义、修改类定义、创建新类,甚至编写自动生成文档的程序。这些类包含在%Dictionary
包。
注意 :
在%Library
包中定义了一组较旧的类定义类 。这些是为了与现有应用程序兼容而维护的。新代码应该使用%Dictionary
包中的类。使用这些类时,请确保指定了正确的包名称,否则可能会无意中使用错误的类。
有两组并行的类定义类:表示已定义类的类 和表示已编译类的类。
- 定义的类定义表示特定类的定义。它仅包含该类定义的信息;它不包括从超类继承的信息。除了提供有关字典中类的信息外,这些类还可用于以编程方式更改或创建新的类定义。
- 编译的类定义包括从超类继承的所有类成员。已编译的类定义对象只能从已编译的类实例化。不能保存已编译的类定义。
本章节只讨论已定义的类定义,尽管已编译类定义的操作类似。
已定义类的类定义类
表示已定义类的类定义类族包括:
Class | 描述 |
---|---|
%Dictionary.ClassDefinition |
表示类定义。包含类关键字以及包含类成员定义的集合 |
%Dictionary.ForeignKeyDefinition | 表示类中的外键定义 |
%Dictionary.IndexDefinition | 表示类中的索引定义. |
%Dictionary.MethodDefinition | 表示类中的方法定义. |
%Dictionary.ParameterDefinition | 表示类中的参数定义. |
%Dictionary.PropertyDefinition | 表示类中的属性定义。 |
%Dictionary.QueryDefinition | 表示类中的查询定义. |
%Dictionary.TriggerDefinition | 表示类中的 SQL 触发器定义。 |
重要:
- 重申一下,未编译的类定义的内容(作为
%Dictionary.ClassDefinition
的实例)不一定与已编译的类定义(作为%Dictionary.CompiledClass
的实例)的内容相同。 %Dictionary.ClassDefinition
类提供了一个API
来检查或更改类的定义 --- 它从不表示已解析继承的已编译类;另一方面,%Dictionary.CompiledClass
确实表示已解析继承的已编译类。- 例如,如果尝试确定类定义中特定关键字 的值,请使用
%Dictionary.ClassDefinition
中的keywordname IsDefined()
方法(如OdbcTypeIsDefined
() 或ServerOnlyIsDefined()
). 如果此布尔方法返回 false,则不会为该类显式定义关键字。如果检查类定义的关键字值,它将是默认值。但是,在编译(包括继承解析)之后,关键字的值由继承确定,并且可能与定义的值不同。
二、浏览类定义
可以使用管理门户的 SQL 页浏览类定义类。
同样,可以使用与浏览任何其他类型的数据相同的技术以编程方式 浏览类定义:可以使用 %ResultSet
对象循环访问类集,并且可以实例化表示特定类定义的持久性对象。
例如,在 Caché
进程中,可以使用 %Dictionary.ClassDefinition:Summary()
查询获取当前命名空间的字典中定义的所有类的列表:
javascript
Set result = ##class(%ResultSet).%New("%Dictionary.ClassDefinition:Summary")
Do result.Execute()
While (result.Next()) {
Write result.Data("Name"),!
}
您可以使用客户端 ResultSet
对象从 ActiveX 或 Java 客户端轻松调用此查询。
%Dictionary.ClassDefinition:ClassInfo()
查询将返回当前命名空间中可见的所有类(包括系统库中的类)。- 您可以使用
%Dictionary.ClassDefinition:Summary()
查询返回的各种列过滤掉不需要的类。
通过打开特定类的 %Dictionary.ClassDefinition
对象并观察其属性,可以获取有关该类定义的详细信息。用于存储 %Dictionary.ClassDefinition
对象的 ID 是类名:
javascript
Set cdef = ##class(%Dictionary.ClassDefinition).%OpenId("Sample.Person")
Write cdef.Name,!
// get list of properties
Set count = cdef.Properties.Count()
For i = 1:1:count {
Write cdef.Properties.GetAt(i).Name,!
}
您也可以从 ActiveX 或 Java 客户端轻松执行此操作。请注意,必须使用类名的包名完全限定类名,否则对 %OpenId()
的调用将失败。
三、更改类定义
可以通过打开 %Dictionary.ClassDefinition
对象,进行所需的更改,然后使用 %Save()
方法保存它来修改现有类定义。
您可以通过创建新的%Dictionary.ClassDefinition
对象、填充其属性并保存来创建新类。
- 创建
%Dictionary.ClassDefinition
对象时,必须通过%New()
命令传递类的名称。 - 如果要向类(如属性或方法)添加成员,必须创建相应的定义类(向其 %New() 命令传递一个包含
"class_name.member_name"
的字符串),并将该对象添加到%Dictionary.ClassDefinition
对象中的相应集合中。
通过代码新建类
javascript
Set cdef = ##class(%Dictionary.ClassDefinition).%New("Demo.Object.MyClass2")
If $SYSTEM.Status.IsError(cdef) {
Do $system.Status.DecomposeStatus(%objlasterror,.Err)
Write !, Err(Err)
}
B ;001
Set cdef.Super = "%Persistent,%Populate"
// add a Name property
Set pdef = ##class(%Dictionary.PropertyDefinition).%New("Demo.Object.MyClass:Code")
If $SYSTEM.Status.IsError(pdef) {
Do $system.Status.DecomposeStatus(%objlasterror,.Err)
Write !,Err(Err)
}
Do cdef.Properties.Insert(pdef)
Set pdef.Type="%String"
B ;002
// save the class definition object
Do cdef.%Save()
Q $$$OK
上述代码将会自动创建类:
javascript
Class Demo.Object.MyClass2 Extends (%Persistent, %Populate) [ Inheritance = right, Not ProcedureBlock ]
{
Property Code As %String;
}
四、%Dictionary.ClassDefinition
打开%Dictionary.ClassDefinition
定义,可以得出该类为持久类,并可以通过在SQL中查询所有的类定义,包括系统类,
- 该类的主Map为:
^oddDEF({%Dictionary.ClassDefinition.Name})
- %Dictionary.ClassDefinition.Name: 为类名,即
ID
为类名.
- SQL查询
- 存储详细
javascript
1: ^oddDEF("QP.Object.MyClass") = 25
2: ^oddDEF("QP.Object.MyClass",1) = "QP.Object.MyClass"
3: ^oddDEF("QP.Object.MyClass",60) = "%Persistent"
4: ^oddDEF("QP.Object.MyClass",63) = "66837,53644.04632"
5: ^oddDEF("QP.Object.MyClass",64) = "66837,52007.491497"
6: ^oddDEF("QP.Object.MyClass","a","Name") = ""
7: ^oddDEF("QP.Object.MyClass","a","Name",4) = "Description"
8: ^oddDEF("QP.Object.MyClass","a","Name",5) = "%String"
9: ^oddDEF("QP.Object.MyClass","a","Name",11) = 1
10: ^oddDEF("QP.Object.MyClass","s","Default",5) = "%Library.CacheStorage"
11: ^oddDEF("QP.Object.MyClass","s","Default",21) = "^QP.Object.MyClassD"
12: ^oddDEF("QP.Object.MyClass","s","Default",22) = "MyClassDefaultData"
13: ^oddDEF("QP.Object.MyClass","s","Default",24) = "^QP.Object.MyClassD"
14: ^oddDEF("QP.Object.MyClass","s","Default",25) = "^QP.Object.MyClassI"
15: ^oddDEF("QP.Object.MyClass","s","Default",33) = "^QP.Object.MyClassS"
16: ^oddDEF("QP.Object.MyClass","s","Default","D","MyClassDefaultData") = ""
17: ^oddDEF("QP.Object.MyClass","s","Default","D","MyClassDefaultData",22) = "listnode"
18: ^oddDEF("QP.Object.MyClass","s","Default","D","MyClassDefaultData",23) = ""
19: ^oddDEF("QP.Object.MyClass","s","Default","D","MyClassDefaultData","V",1) = ""
20: ^oddDEF("QP.Object.MyClass","s","Default","D","MyClassDefaultData","V",1,21) = "%%CLASSNAME"
21: ^oddDEF("QP.Object.MyClass","s","Default","D","MyClassDefaultData","V",2) = ""
22: ^oddDEF("QP.Object.MyClass","s","Default","D","MyClassDefaultData","V",2,21) = "Name"
五、其余%Dictionary.xxxDefinition类
- %Dictionary.QueryDefinition 查询定义类
- %Dictionary.ForeignKeyDefinition 表示类中的外键定义。
- %Dictionary.IndexDefinition 表示类中的索引定义。
- %Dictionary.MethodDefinition 表示类中的方法定义。
- %Dictionary.ParameterDefinition 表示类中的参数定义。
- %Dictionary.PropertyDefinition 表示类中的属性定义。
- %Dictionary.QueryDefinition 表示类中的查询定义。
- %Dictionary.TriggerDefinition 表示类中的 SQL 触发器定义。
- ... 等等
这些类分析的方式和上述%Dictionary.ClassDefinition
分析相同。不再此赘述。