一、概述
对象是Oracle8i以上版本中的一个新的特性,对象实际是对一组数据和操作的封装,对象的抽象就是类。在面向对象技术中,对象涉及到以下几个重要的特性:
封装性
通过对数据和操作的封装,将用户关心的数据和操作暴露出来作为接口,其他数据和操作则隐藏到对象内部,这样便于用户使用和维护。
继承性
对象具有继承性,通过这一特性可以增强程序的可扩展性,适合大型项目的开发。
多态性
同一操作在运行时刻有不同的对象来引用,则其执行结果是不一样的。这一特性称之为多态性。
正是因为面向对象的诸多优势,Oracle公司在8.0版本以后就加入了对这一特性的全面支持,下来的部分重点讲述在Oracle中的面向对象程序设计。
二、Oracle中的面向对象程序设计
既然对象具有这么多的优点,那么在Oracle数据库如何引用它呢?Oracle中的对象定义分两步进行:
首先定义对象类型。定义对象类型跟定义包类型完全一样,即分为对象类型头(或称为对象规范,specification)和对象类型体(body)。对象类型头包括了对象类型的属性和方法的声明,而对象类型体则包含了对象类型具体的实现。
例如,定义一个empObj对象类型,代码如下:
create or replace type empObj as object (emp_id number(5),emp_name varchar2(20),emp_salary number(4),--object’s functionmember function addsalary(ext_salary number) return varchar2,);--object's bodycreate or replace type body empObj asmember function addsalaryreturn varchar2 isbeginemp_salary :=emp_salary +ext_salary ;return to_char(emp_salary);end addsalary;end;
特别需要注意的是,如果对象没有成员函数部分,那么此对象类型的定义只有对象类型头部分。
然后定义对象实例。定义了对象类型后就可以直接定义它的实例了,比如定义一个empObj实例对象,代码如下:
v_empObj1 empObj;
经过这两步之后就可以引用对象实例的属性和方法了,引用符号为“.”,比如
v_empObj1.emp_id; //引用emp_id属性v_empObj1.addsalary(300); //引用addsalary方法
另外,在初始化无成员函数的对象时可以直接以构造函数的形式进行初始化,注意,这个时候不需显式的定义构造函数。比如,初始化上面v_empObj1对象(假设无成员函数的情况下才能进行这种初始化操作), 代码如下:
v_empObj1 empObj:=empObj(10005,’jack’,6500);
由于Oracle数据库是关系型数据库,其存储数据是以二维表的形式进行的,而对象是对数据和操作进行封装的一个实体,其存储信息往往是多维信息,那么对象在Oracle数据库中的存储是如何进行的呢?(这里补充一点,PL/SQL程序块中声明的对象是临时对象,在超出其作用区域后系统将自动收回其分配的资源,但是如果需要保存对象的信息,就必须将其存储在数据库中)
事实上,对象在Oracle数据库中的存储形式分为两种:
1. 对象列。即可以将数据表中的列的数据类型定义为一个对象类型,这样对象就可以存储在数据列中了。比如定义一个表table1,其中emp列可以用来存储对象。
create table table1(id number(2);emp empObj;);
2. 对象行。即可以创建一个对象表,其中每一列就表示对象中的一个属性,这样一条行记录就是一个对象了。比如定义一个emp表如下:
create table emp(emp_id number(5);emp_name varchar2(20);emp_salary number(4););
这样emp表的一个记录就是一个empObj对象,插入一个表的操作就可以为:
insert into emp values (empObj(10006,'marry',5000));
注意,这里表中列类型与对象的属性类型应该一一对应,另外这样存储将忽略对象的成员函数的信息。
三、对象操作与比较
可以采用DML语句对对象进行操作,其操作的语法跟一般的数据类型完全一样,比如在table1表中返回对象为empObj(10002,’mike’,3000)的记录:
select * from table1 where emp=empObj(10002,'mike',3000);
如果需要进行对象的大小比较,那么用一般的方法就很难处理,毕竟对象含有一组属性,无法进行组合比较。可以采用向对象加入map方法和order方法来解决此问题,前者是通过将对象某一属性返回代表对象的值班来比较大小,后者是通过比较两个对象之间某个属性的值班来获取对象的大小。由于两者的相似性,这里以用途更广的map成员函数为为例示范如下:
create or replace type empObj as object (
emp_id number(5),
emp_name varchar2(20),
emp_salary number(4),
--object’s function
member function addsalary(ext_salary number) return varchar2,
map member function ID return number);--object's bodycreate or replace type body empObj as member function addsalary return varchar2 isbegin
emp_salary :=emp_salary +ext_salary ;
return to_char(emp_salary);end addsalary;--map function's bodymap member function ID return number isbegin
return emp_id;
end ID;end;
这样定义了map函数后,对empObj对象大小的比较实质转化为对各个对象的emp_id属性大小的比较,在实际操作中,应该根据实际情况来返回关心的数据,以进行对象大小比较的操作。
四、小结
通过前面内容的介绍,大家应该对Oracle数据库的面向对象的特性有一个初步的认识,充分利用Oracle的这一特性,可以将面向对象的重用性,可扩展性等优点引入到数据库中,提高了数据库的运行性能。