文章
· 八月 6 阅读大约需 4 分钟

InterSystems ObjectScript中一些有用的自动生成的方法

在使用 InterSystems ObjectScript 进行编程时,当你定义了属性property、查询query或者索引index,系统会在编译的过程中自动创建与之相关的一些方法,这篇文章对这些方法做了些总结:

 

属性Properties

1. 假设你定义了一个属性 Property, 下面的方法会被自动创建

ClassMethod PropertyGetStored(id)

对于数据类型属性,这个函数将返回其逻辑值,对于对象属性,返回id。这是一个对类global数据的封装,也是获取单例属性值(singular property value)最快的方法。此方法仅适用于已持久化存储的属性。

这里是一段采用多种方法读取数据的对比代码,用于测试各种访问数据方式的时间差异,其结果是:

Iterations: 10000
Object access: .130111
GetStored access: .014388
SQL access: .020268
Global access: .007717
Object access takes 904.30% of GetStored time
Object access takes 641.95% of SQL time
Object access takes 1686.03% of Global time
GetStored access takes 70.99% of SQL time
GetStored access takes 186.45% of Global time
SQL access takes 262.64% of Global time

其中:

  • Object access 是打开一个对象,并读取其属性值
  • SQL access 使用嵌入式SQL
  • GetStored 使用本文所述自动生成的方法
  • Global 使用直接读取保存属性值的global

2. 

Method PropertyGet()

这个函数是属性的getter,可被重新定义。

3.

Method PropertySet(val) As %Status

这个函数是属性的setter, 可被重新定义。

 

对象属性 Object properties

1. 如果是一个对象属性,有关ID以及OID的方法会被创建

Method PropertySetObjectId(id)

这个方法通过对象的Id设置属性值,也就是不需要首先打开一个对象,再设置该对象的属性值。

例如下面定义了两个类

Class Person Extents %Persistent {

Property EmployedAt As Company;
}


Class Company Extends %Persistent {

}

通常来说你要将Company赋值给Person是这样写的:

set person = ##class(Person).%New()
set companyId = 123
set company = ##class(Company).%OpenId(companyId)
set person.EmployedAt = company

但是如果你使用PropertySetObjectId方法,就可以这样写:

set person = ##class(Person).%New()
set companyId = 123
do person.EmployedAtSetObjectId(companyId)

可以看到,这样写的不同点就是,你不需要打开Company这个对象,就可以直接赋值。

2. 

Method PropertyGetObjectId()

这个方法返回属性值的Id

3. 

Method PropertySetObject(oid)

这个方法通过OID设置属性值

4. 

Method PropertyGetObject()

这个方法返回属性值的OID

 

数据类型属性Datatype properties

1. 对于数据类型属性会生成多个在不同格式间转换的函数:

ClassMethod PropertyDisplayToLogical(val)
ClassMethod PropertyLogicalToDisplay(val)
ClassMethod PropertyOdbcToLogical(val)
ClassMethod PropertyLogicalToOdbc(val)
ClassMethod PropertyXSDToLogical(val)
ClassMethod PropertyLogicalToXSD(val)
ClassMethod PropertyIsValid(val) As %Status

检查val是否为有效的属性值

2.

ClassMethod PropertyNormalize(val)

返回标准化的逻辑值

注意:

  • 定义的关系(Relationship)也是属性,可以使用 get/set 方法
  • 输入值 val 总是指逻辑值,格式转换方法除外

 

索引Indexes

1. 对于命名为"Index"的索引,下面函数会被自动创建

ClassMethod IndexExists(val) As %Boolean

该函数判断val的索引是否存在。

 

唯一索引Unique Indexes

1. 对于唯一索引,下面函数会被自动创建

ClassMethod IndexExists(val, Output id) As %Boolean

判断val的索引是否存在,并且通过第二个参数返回该对象的id。

2. 

ClassMethod IndexDelete(val, concurrency = -1) As %Status

通过val,删除索引

3. 

ClassMethod IndexOpen(val, concurrency, sc As %Status)

通过val返回该对象。

注意: 

  • 索引可基于多个属性创建,如何使基于多个属性创建的索引,那么函数的输入参数则是多个,比如这样的索引定义:
Index MyIndex On (Prop1, Prop2);

那么IndexExists函数则会是下面这样的:

ClassMethod IndexExists(val1, val2) As %Boolean

其中val1对应于Prop1的值, val2对应于Prop2的值,其他的函数遵循同样的逻辑。

  • Caché 生成的 IDKEY索引,是基于ID字段创建的索引。它同样可被重写,以及包含多个属性。例如,检查该类是否有某属性定义:
Write ##class(%Dictionary.PropertyDefinition).IDKEYExists(class, property)
  • 所有索引函数检查的都是逻辑值
  • 文档参见这里

 

查询Queries

1. 对于查询queries(它可以是一个简单的SQL查询,或者用户自定义的类的查询),命名为"Query"Func的方法会被自动创建:

ClassMethod QueryFunc(Arg1, Arg2) As %SQL.StatementResult

它会返回一个 %SQL.StatementResult,可被用于便利查询。比如对于在Samples命名空间下的Sample.Person类,定义了一个ByName的查询,它接受一个输入参数,它可以直接通过下面方法在代码中调用:

Set ResultSet=##class(Sample.Person).ByNameFunc("A")
While ResultSet.%Next() { Write ResultSet.Name,! }

另外,这里是一个在GitHub上的示例,用于演示上面的方法使用。

讨论 (0)1
登录或注册以继续