第三十九章 持久对象和SQL - 持久类的 SQL 映射
持久类的 SQL 映射
对于任何持久类,该类的每个实例都可以作为表中的一行使用,可以通过 SQL
查询和操作该行。为了演示这一点,本节使用管理门户和终端。
对象 SQL 映射的演示
考虑 SAMPLES
中的 Sample.Person
类。如果我们使用管理门户来显示与该类对应的表的内容,我们会看到如下内容:
请注意以下几点:
- 此处显示的值是显示值,而不是存储在磁盘上的逻辑值。
- 第一列 (
#
) 是该显示页面中的行号。 - 第二列(
ID
)是该表中行的唯一标识符;这是打开此类对象时使用的标识符。 (在此类中,这些标识符是整数,但这并不总是正确的。)
在本例中,这些数字恰好相同,因为每次构建 SAMPLES
数据库时都会重新填充该表。在实际应用中,有可能某些记录已被删除,从而导致ID值存在间隙,并且这些值与行号不匹配。
在终端中,我们可以使用一系列命令来查看第一人称:
SAMPLES>set person=##class(Sample.Person).%OpenId(1)
SAMPLES>write person.Name
Newton,Dave R.
SAMPLES>write person.FavoriteColors.Count()
1
SAMPLES>write person.FavoriteColors.GetAt(1)
Red
SAMPLES>write person.SSN
384-10-6538
>>> person=iris.cls("Sample.Person")._OpenId(1)
>>> print(person.Name)
Newton,Dave R.
>>> print(person.FavoriteColors.Count())
1
>>> print(person.FavoriteColors.GetAt(1))
Red
>>> print(person.SSN)
384-10-6538
这些值与我们通过 SQL
看到的值相同。
对象 SQL
映射的基础知识
由于继承不是关系模型的一部分,因此类编译器将持久类的“扁平”表示映射为关系表。下表列出了一些不同的对象元素如何投影到 SQL
:
Object Concept | SQL Concept |
---|---|
Package | Schema |
Class | Table |
Property | Field |
Embedded object | Set of fields |
List property | List field |
Array property | Child table |
Stream property | BLOB or CLOB |
Index | Index |
Class method marked as stored procedure | Stored procedure |
映射表包含该类的所有适当字段,包括继承的字段。
Classes and Extents
IRIS
使用一种非常规且强大的对象表映射解释。
持久类的所有存储实例组成了所谓的类extent
,一个实例属于它作为实例的每个类的范围。所以:
- 如果持久类
Person
有子类Student
,则Person
范围包括Person
的所有实例和Student
的所有实例。 - 对于
Student
类的任何给定实例,该实例都包含在Person
范围和Student
范围中。
索引自动跨越定义它们的类的整个范围。 Person
中定义的索引包含 Person
实例和 Student
实例。 Student
范围中定义的索引仅包含 Student
实例。
子类可以定义其超类中未定义的附加属性。这些在子类范围内可用,但在超类范围内不可用。例如,Student
范围可能包括FacultyAdvisor
字段,该字段不包括在Person
范围中。
上述几点意味着在 IRIS
中编写检索相同类型的所有记录的查询相对容易。例如,如果想要统计所有类型的人员,可以对 Person
表运行查询。如果只想计算学生数量,请对 Student
表运行相同的查询。相反,对于其他对象数据库,要对所有类型的人员进行计数,则需要编写组合表的更复杂的查询,并且每当添加另一个子类时都需要更新此查询。