Swallow Object Database.
1. 简介
Swallow 是在关系数据库的基础上实现的面向对象的数据库组件。它利用O/R Mapping的原理来模拟实现一个面向对象的数据库。
与现有的一些O/R Mapping组件相比,Swallow支持更加全面的面向对象的概念,在Swallow中开发者可以定义类,可以增删和修改类的属性,并且类之间可以继承,子类可以重载父类的属性,并且支持多态。对父类对象数据的查询,会返回包括子类在内的所有符合条件的数据;并且与现在国外已经研究出来的OODB产品相比具有方便的类SQL查询功能。在Swallow中支持OQL(Object Query Language)查询语言,语法类似于SQL语句,但是可以查询和返回复杂的对象数据。
2. 已开发的Swallow尝试版
目前已经尝试开发了Swallow Trivial Edition for Microsoft Access,主要基于COM技术,吸取了ADO编程模型以及VB等程序设计语言的相关思想。
Swallow组件的编程模型(Object Model):
以上的编程模型与微软的ADO以及ADOX编程模型在结构上有些类似。图中,白色方框代表集合,灰色方框代表对象。
Schema部分:
l Database: 代表整个Swallow数据库。一个数据库由多个Library组成。
l Library: 每个库中可以存放类(Class),枚举(Enumeration),OQL查询(Query),变量(Variable)的Schema信息。 之所以在引入Library的概念,其实主要是为了防止命名的冲突,有点类似于名称空间。这样数据库中一个类的完整的名称应该为LibraryName:ClassName。
l Class: 代表一个类的定义,包含了一组属性(Attribute)的集合。目前Class的属性只是数据字段,还不支持编程语言中的方法。Class中的Attribute可以是Role,通过Role来指向其它类中的对象,类似于C++中“引用”的概念。Class的属性除了是基本数据类型之外,也可以是另外一个Class,这样支持嵌套的复杂的“结构体”。另外Class的所有对象的实体可以来自于不同的区域(Region),比如来自于某个子类,或者来自于某个嵌套的属性。在查询某个类的对象的时候可以通过指定具体的Region来返回更精确的对象。
l Query: 有点类似于关系数据库中视图(View)的概念。其实就是把定义好的OQL解析后存储在数据库中,以后要执行同一个查询,无需再写OQL语句,只要直接Query的标识符来执行查询就可以了。
l Enumeration: 类似于编程语言中的枚举类型的概念,其实是一种关系约束。开发人员可以Class的某个属性指定为Enumeration,那么那个属性的取值只能是Enumeration中规定的几个对象之一。
l Variable: 其实是可以给数据库中的代表某个对象的数据记录加上一个标识符,这样可以通过一个可读性比较好的名字直接找到一个对象的数据,不必通过对象的唯一ID。
Manipulation部分:
l Object: 每个Object代表某个Class的一个对象实体。存放了对象的数据。可以通过Property集合来检索对象的属性中存放的数据,与Attribute对应可以包含复杂的结构体。另外如果一个属性是引用了另外一个对象的话,可以通过Member集合来访问成员对象。
l Objectset: 是一组Object的集合,类似于ADO中的Recordset,可以来回移动,检索集合中的每一个对象。
l Dataset:同样类似于ADO中的Recordset,并且具有类似的方法来检索数据。与Objectset不同的地方在于,Objectset是一个一唯的Object链表,而Dataset是一个二维的Table,其中每一条记录有多个Sector组成,每个Sector其实类似于Recordset.Field,但是它可以存放复杂的对象数据。
Swallow 支持的数据类型:
Swallow支持19种类型,其中包括13种基本数据类型,6种复合类型。(具体的数据类型参见附件Swallow Data Types.doc)
基本类型:Boolean, Byte, Short, Integer, Long, Single, Double, Currency, DateTime, Decimal, String, Memo, Image。
复合类型:
Enumerated: 枚举类型,这种类型的属性的取值只能够是枚举类型中定义的几个对象之一;
Array:数组类型,通过序号来唯一的确定和检索一个集合中的对象数据;
Set:代表一组无序的对象的集合;
Dictionary:代表一个对象的集合,并且集合中的每个元素都被赋予一个唯一的Key,通过Key类检索对象;
Pointer:存放了某个对象在数据库中存放的地址信息,通过它可以指向数据库中另外一个对象;
Object:是最常用的类型,表示一个对象,可以存放复杂的嵌套的结构体数据。
Swallow演示
下面的一些截图是取自用VB写的一个测试程序,该测试程序调用了Swallow的OODB.dll组件,显示出一个简单的Swallow数据库中的Schema信息。
Hierarchical Inheritance Tree: 这幅图显示了数据库中定义的所有的Class的继承关系树。从中可以看到所有的Class都继承自系统的Object类。
Structured Classes: 在Swallow中定义的属性除了是简单的基础数据类型以外,还可以是复合类型,支持复杂的结构体嵌套。下图中,Class”帖子” 和 “短消息” 定义了类型为Class”用户”的属性。
Inheritance and Polymorphism:在Swallow中对基类的对象的查询可以返回所有派生类中的对象。下图中派生类”管理员”,”贵宾”中的对象,在父类”用户”中也出现了。
Create Classes Programmatically: 下面是在VB6中定义Class的代码片断。
Object Query Language ---- An Extension of SQL.
在OQL中可以用Object.Property.Property的形式出现在Select语句中,而且在From子句中可以出现Class的任何一个Region。
下图是在asp页面中调用Swallow组件来运行一个OQL查询的例子:
在返回的结果集Dataset中可以包括复杂的对象。如下图所示,图中代表一个Dataset中的第251条记录:
Handling
Relationships between Objects more conveniently:
在Swallow中还可以很方便的帮你处理对象与对象之间的关系。假如有三个Class”婚姻”,”丈夫”和”妻子”。其中婚姻中有两个属性分别是对丈夫对象和妻子对象的引用。它们是两个Role。那么在Swallow中可以很方便的通过objHusband.GetRelationObjectset(“丈夫”, “婚姻”, “妻子”)方法返回所有的妻子对象,而不需要再去用Select和join语句查询了。
3. 未来Swallow.NET的展望:
上面只是已经实现的一个简单的Swallow Trivial Edition。希望在以后的发展中Swallow能够与Microsoft .NET Framework紧密集成,成为.net平台的持久化组件。具体在如下的几个方面进行修改和增强:
l 基础数据类型完全与.NET Framework支持的基础类型相同。并且Array和Dictionary类型将变为.net中的ArrayList和Hashtable。
l 为了更好的和.net集成,Swallow.NET的编程模型将进一步的模仿.NET Framework的面向对象的结构。比如Library换成NameSpace并且可以嵌套namespace。
l 利用.NET的反射(Reflection)机制,用户只需要在定义类的时候在类和相应的属性字段的前面添加相应的Attribute标记,就可以在编译的时候自动解析代码中类的结构并在后台的数据库中自动创建和维护相应的Swallow Class与之对应。开发人员甚至可以忽略数据库的存在,专心于面向对象的代码的编写。
l 返回真正的对象。在.net中利用Activator直接将查询结果Dataset中的数据组装成二进制的真正的.net对象。对于开发人员更加方便。并且真正的实现多态。
l 由于Swallow的编码实现中只用到了最基本的SQL语句,所以可以较方便的支持多种关系数据库,甚至包括Access等小型桌面数据库。