第二十二章 Caché 定义数据类型类

文章目录

  • 第二十二章 Caché 定义数据类型类
  • 数据类型类概述
    • 属性方法
    • 数据格式
    • 数据类型类中的参数
  • 定义数据类型类
  • 在数据类型类中定义类方法
  • 在数据类型类中定义实例方法

第二十二章 Caché 定义数据类型类

数据类型类概述

数据类型类的用途是用作对象类中的文本属性的类型。数据类型类提供以下功能:

  • 它们通过提供SQL逻辑操作、客户端数据类型和转换信息来提供SQL、ODBC、ActiveX和Java互操作性。

  • 它们为文字数据值提供验证,可以使用数据类型类参数对其进行扩展或自定义。

  • 它们管理文字数据的存储(在磁盘上)、逻辑(在内存中)和显示格式的转换。

数据类型类在许多方面与其他类不同:

  • 它们不能独立实例化或存储。

  • 它们不能包含属性。

  • 它们支持一组特定的方法(称为数据类型接口),如下所述。

由于了解一些内部细节很有用,因此本节简要讨论数据类型类的工作方式。

如前所述,数据类型类的用途是用作属性的类型,特别是在扩展核心对象类之一的类中。下面显示了一个具有三个特性的样例对象类。每个属性都使用一个数据类型类作为其类型。

Class Datatypes.Container Extends %RegisteredObject
{

Property P1 As %String;

Property P2 As %Integer;

Property P3 As %Boolean;

}

属性方法

向类添加文本属性并编译该类时,caché会向该类添加属性方法。作为参考,让我们使用术语容器类来指代包含属性的类。属性方法控制容器类如何处理这些属性的数据。

该系统的工作方式如下:

  • 每个数据类型类都提供一组方法,更具体地说是方法生成器,在编译使用它们的类时,Caché会使用这些方法方法生成器是一种生成自己的运行时代码的方法。

在这里显示的示例中,当我们编译Datatypes.Container时,编译器使用%String、%Integer和%Boolean数据类型类的方法生成器。这些方法生成器为每个属性创建方法,并将这些方法添加到容器类。如上所述,这些方法称为属性方法。它们的名称以它们所应用的属性的名称开头。例如,对于P1属性,编译器生成诸如P1IsValid()、P1Normalize()、P1LogicalToDisplay()、P1ToDisplayToLogical()等方法。

  • 容器类在处理过程中的适当位置自动调用属性方法。例如,当为上面显示的类的实例调用%ValidateObject()实例方法时,该方法依次调用P1IsValid()、P2IsValid()和P3IsValid()-也就是说,它为每个属性调用IsValid()方法。再举一个例子,如果容器类是持久化的,并且使用CachéSQL访问关联表中的所有字段,并且SQL运行时模式是ODBC,则Caché将为每个属性调用LogicalToODBC()方法,以便查询以ODBC格式返回结果。

请注意,属性方法在类定义中不可见。

数据格式

许多属性方法将数据从一种格式转换为另一种格式,例如,当以人们可读的格式显示数据或通过ODBC访问数据时。

格式为:

  • Display 可以输入和显示数据的格式。例如,“April 3, 1998”或“23 November, 1977”形式的日期。
  • Logical 内存中的数据格式,这是要对其执行操作的格式。虽然日期的显示格式如上所述,但它们的逻辑格式是整数;对于上面的示例日期,它们的逻辑格式值分别是57436和50000。
  • Storage 数据的磁盘格式-数据存储到数据库的格式。通常,这与逻辑格式相同。
  • ODBC 可以通过ODBC或JDBC呈现数据的格式。此格式在向ODBC/SQL公开数据时使用。可用的格式与ODBC定义的格式相对应。
  • XSD SOAP编码格式。导出为XML或从XML导入时使用此格式。这仅适用于启用XML的类。

数据类型类中的参数

类参数在与数据类型类一起使用时具有特殊行为。对于数据类型类,类参数用于提供一种基于数据类型自定义任何属性行为的方法。

例如,%Integer数据类型类有一个类参数MAXVAL,它指定%Integer类型的属性的最大有效值。如果使用属性NumKids定义类,如下所示:

Property NumKids As %Integer(MAXVAL=10);

这指定NumKids属性的%Integer类的MAXVAL参数将设置为10。

在内部,这是这样工作的:标准数据类型类的验证方法都实现为方法生成器,并使用它们的各种类参数来控制这些验证方法的生成。

在此示例中,此属性定义为NumKidsIsValidDT()方法生成内容,该方法测试NumKidsIsValidDT()的值是否超过10。如果不使用类参数,创建此功能将需要定义IntegerLessThanTen类。

定义数据类型类

若要定义数据类型类,请首先标识最接近你需要的现有数据类型类。创建此类的子类。在的子类中:

  • 为关键字SqlCategory、ClientDataType和OdbcType指定合适的值。
  • 根据需要重写任何类参数。例如,可以替代MAXLEN参数,以使特性没有长度限制。

如果需要,还可以添加自己的类参数。

  • 根据需要重写数据类型类的方法。在的实现中,请根据需要引用该类的参数。

如果数据类型类不是基于现有的数据类型类,请确保将[ClassType=DataType]添加到类定义中。如果类基于另一个数据类型类,则不需要此声明。

在数据类型类中定义类方法

根据需要,应该在数据类型类中定义以下部分或全部类方法:

  • IsValid() 在适当的情况下使用特性参数执行特性的数据验证。如前所述,任何Object类的%ValidateObject()实例方法都会为每个属性调用IsValid()方法。
ClassMethod IsValid(%val) As %Status 

其中%val是要验证的值。如果值无效,此方法应返回错误状态,否则应返回$OK。

注意:Caché中的标准做法是不调用空值的验证逻辑。

  • Normalize() 将属性的数据转换为标准表单或格式。任何Object类的%NormalizeObject()实例方法都会为每个属性调用Normalize()方法。
ClassMethod Normalize(%val) As Type 

翻译:

其中%val是要验证的值,Type是合适的类型类。

  • DisplayToLogical() 将显示值转换为逻辑值。
ClassMethod DisplayToLogical(%val) As Type 

其中%val是要转换的值,Type是合适的类型类。

其他格式转换方法具有相同的形式。

  • LogicalToDisplay() —将逻辑值转换为显示值。
  • LogicalToOdbc() — 将逻辑值转换为ODBC值。

请注意,ODBC值必须与数据类型类的 ODBC Type类关键字指定的ODBC类型一致。

  • LogicalToStorage() — 将逻辑值转换为存储值。
  • LogicalToXSD() — 将逻辑值转换为适当的SOAP编码值。
  • OdbcToLogical() — 将ODBC值转换为逻辑值。
  • StorageToLogical() — 将数据库存储值转换为逻辑值。
  • XSDToLogical() — 将SOAP编码值转换为逻辑值。

如果数据类型类包括DISPLAYLIST和VALUELIST参数,则这些方法必须首先检查是否存在这些类参数,并包含处理这些列表的代码。其他方法的逻辑与此类似。

在大多数情况下,这些方法中的许多都是方法生成器。

例如:

ClassMethod LogicalToDate(%val As %MV.Date) As %Library.Date [ CodeMode = expression, ServerOnly = 1 ]
{
$s(%val="":"",1:%val+46385)
}

注意:请注意,数据格式和转换方法不能包含嵌入式SQL。如果需要在此逻辑中调用嵌入式SQL,则可以将嵌入式SQL放在单独的例程中,该方法可以调用此例程。

在数据类型类中定义实例方法

还可以向数据类型类添加实例方法,这些方法可以使用变量%val,该变量包含属性的当前值。编译器使用它们在使用数据类型类的任何类中生成关联的属性方法。

例如,考虑以下示例数据类型类:

Class Datatypes.MyDate Extends %Date
{

Method ToMyDate() As %String [ CodeMode = expression ]
{
$ZDate(%val,3)
}
}

假设我们有另一个类,如下所示:

Class Datatypes.Container Extends %Persistent
{

Property DOB As Datatypes.MyDate;


}

当我们编译这些类时,Caché会将实例方法DOBToMyDate()添加到容器类中。然后,当我们创建CONTAINER类的实例时,我们可以调用此方法。例如:

SAMPLES>set instance=##class(Datatypes.Container).%New()
 
SAMPLES>set instance.DOB=+$H
 
SAMPLES>write instance.DOBToMyDate()
30/10/2014

你可能感兴趣的:(Caché,从入门到精通)