在使用 InterSystems ObjectScript 进行编程时,当你定义了属性property、查询query或者索引index,系统会在编译的过程中自动创建与之相关的一些方法,这篇文章对这些方法做了些总结:
属性Properties
1. 假设你定义了一个属性 Property, 下面的方法会被自动创建
ClassMethod PropertyGetStored(id)
ObjectScriptObjectScript
对于数据类型属性,这个函数将返回其逻辑值,对于对象属性,返回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
ObjectScriptObjectScript
其中:
- Object access 是打开一个对象,并读取其属性值
- SQL access 使用嵌入式SQL
- GetStored 使用本文所述自动生成的方法
- Global 使用直接读取保存属性值的global
2.
Method PropertyGet()
ObjectScriptObjectScript
这个函数是属性的getter,可被重新定义。
3.
Method PropertySet(val) As %Status
ObjectScriptObjectScript
这个函数是属性的setter, 可被重新定义。
对象属性 Object properties
1. 如果是一个对象属性,有关ID以及OID的方法会被创建
Method PropertySetObjectId(id)
ObjectScriptObjectScript
这个方法通过对象的Id设置属性值,也就是不需要首先打开一个对象,再设置该对象的属性值。
例如下面定义了两个类
Class Person Extents %Persistent {
Property EmployedAt As Company;
}
Class Company Extends %Persistent {
}
ObjectScriptObjectScript
通常来说你要将Company赋值给Person是这样写的:
set person = ##class(Person).%New()
set companyId = 123
set company = ##class(Company).%OpenId(companyId)
set person.EmployedAt = company
ObjectScriptObjectScript
但是如果你使用PropertySetObjectId方法,就可以这样写:
set person = ##class(Person).%New()
set companyId = 123
do person.EmployedAtSetObjectId(companyId)
ObjectScriptObjectScript
可以看到,这样写的不同点就是,你不需要打开Company这个对象,就可以直接赋值。
2.
Method PropertyGetObjectId()
ObjectScriptObjectScript
这个方法返回属性值的Id
3.
Method PropertySetObject(oid)
ObjectScriptObjectScript
这个方法通过OID设置属性值
4.
Method PropertyGetObject()
ObjectScriptObjectScript
这个方法返回属性值的OID
数据类型属性Datatype properties
1. 对于数据类型属性会生成多个在不同格式间转换的函数:
ClassMethod PropertyDisplayToLogical(val)
ClassMethod PropertyLogicalToDisplay(val)
ClassMethod PropertyOdbcToLogical(val)
ClassMethod PropertyLogicalToOdbc(val)
ClassMethod PropertyXSDToLogical(val)
ClassMethod PropertyLogicalToXSD(val)
ObjectScriptObjectScript
ClassMethod PropertyIsValid(val) As %Status
ObjectScriptObjectScript
检查val是否为有效的属性值
2.
ClassMethod PropertyNormalize(val)
ObjectScriptObjectScript
返回标准化的逻辑值
注意:
- 定义的关系(Relationship)也是属性,可以使用 get/set 方法
- 输入值 val 总是指逻辑值,格式转换方法除外
索引Indexes
1. 对于命名为"Index"的索引,下面函数会被自动创建
ClassMethod IndexExists(val) As %Boolean
ObjectScriptObjectScript
该函数判断val的索引是否存在。
唯一索引Unique Indexes
1. 对于唯一索引,下面函数会被自动创建
ClassMethod IndexExists(val, Output id) As %Boolean
ObjectScriptObjectScript
判断val的索引是否存在,并且通过第二个参数返回该对象的id。
2.
ClassMethod IndexDelete(val, concurrency = -1) As %Status
ObjectScriptObjectScript
通过val,删除索引
3.
ClassMethod IndexOpen(val, concurrency, sc As %Status)
ObjectScriptObjectScript
通过val返回该对象。
注意:
- 索引可基于多个属性创建,如何使基于多个属性创建的索引,那么函数的输入参数则是多个,比如这样的索引定义:
Index MyIndex On (Prop1, Prop2);
ObjectScriptObjectScript
那么IndexExists函数则会是下面这样的:
ClassMethod IndexExists(val1, val2) As %Boolean
ObjectScriptObjectScript
其中val1对应于Prop1的值, val2对应于Prop2的值,其他的函数遵循同样的逻辑。
- Caché 生成的 IDKEY索引,是基于ID字段创建的索引。它同样可被重写,以及包含多个属性。例如,检查该类是否有某属性定义:
Write ##class(%Dictionary.PropertyDefinition).IDKEYExists(class, property)
ObjectScriptObjectScript
- 所有索引函数检查的都是逻辑值
- 文档参见这里
查询Queries
1. 对于查询queries(它可以是一个简单的SQL查询,或者用户自定义的类的查询),命名为"Query"Func的方法会被自动创建:
ClassMethod QueryFunc(Arg1, Arg2) As %SQL.StatementResult
ObjectScriptObjectScript
它会返回一个 %SQL.StatementResult,可被用于便利查询。比如对于在Samples命名空间下的Sample.Person类,定义了一个ByName的查询,它接受一个输入参数,它可以直接通过下面方法在代码中调用:
Set ResultSet=##class(Sample.Person).ByNameFunc("A")
While ResultSet.%Next() { Write ResultSet.Name,! }
ObjectScriptObjectScript
另外,这里是一个在GitHub上的示例,用于演示上面的方法使用。