数据封装在vc中的应用

类别:VC语言 点击:0 评论:0 推荐:

数据封装在vc中的应用

1.前言

       在vc的应用程序中,经常要涉及到数据库的操作。如果是很简单的应用,vc还算应付的过去,而对于稍微复杂一点的数据应用,vc开发出来的应用程序就需要编写大量操作数据库的代码,这些代码重复率高,操作com类型的数据,很容易出错。

虽然VC6和VC7中有开发数据库应用的向导,它把数据表封装成类,但这些向导只能在文档类型的应用中采用,如果有多个表,并且有可能需要反复的修改,它就很难满足要求。还有最重要的一点,vc中自带的数据表封装类,是针对odbc等数据连接方式的,它是老套的c/s方式的应用,现在大多应用都是基于多层设计的,数据库的连接管理由中间件管理,这种方式已经不能满足要求。

下面我们将介绍一种简单、广泛、实用的数据库的封装方案,所有的讨论是基于vc6的oracle数据应用,但它不仅限于这些平台,只要稍做修改,同样适用于java下的数据封装。

2.数据封装的规范

在进行封装之前,首先要制定数据封装的规范,说明封装的层次结构,进而才能编写程序。

规范1:每一个数据表或者视图都在VC中建立一个类,该类是数据表或视图的一个映射,它的不同类型的成员变量保存数据表或视图字段的值,该类的一个对象对应数据表或者视图的一条记录。

规范2:每一个数据表的类都是继承于CDataTable类的;每一个视图的封装类都是继承于CDataRec的,CDataTable继承于CDataRec,CDataRec继承于CDataModule,如下图(以用户信息表Yhxxb和用户信息表视图Yhxxb_v为例):

数据封装类中各类的说明:

Ø        CDataModule是数据库操作的封装类,它作为一个通用类可以单独使用,在上图中它作为保护型基类,是因为数据封装类CYhxxb只能够调用CDataRec层以上的已经封装好的函数,而不能直接调用CDataModule类的成员函数直接和数据库交互。

Ø        CDataRec是一个十分关键的类,保存了查询的结果集RecordSet,声明了FillAllField虚函数,利用C++的多态性,在此处调用不同子类的FillAllField函数把查询的结果数据组装到不同的子类对象中。

Ø        CDataTable封装了数据表的一些操作,包括增、删、改等。

Ø        CYhxxb封装了对数据表yhxxb的操作,它可以对其进行增、删、改、查询。

Ø        Cyhxxb_v封装了视图Yhxxb_v的操作,它可以对其进行查找。

3.数据封装的优缺点

按照上面的规范进行数据封装的优点如下:

Ø        CDataModule封装了所有的数据库的操作,它把数据库的操作全部规范起来,整个程序统一由它和数据库交互,使用简单,如果数据库选型改变,或者程序的结构有两层改为三层,仅仅修改该类即可,增加了程序的可移植性。

Ø        层次结构清楚,条理清晰,不同的类负责不同层次的操作,除了最终的表和视图的类,其它的基础类很容易修改。

Ø        最终的类是由程序自动生成,修改也十分容易。

Ø        不容易出错,数据是作为类来出现的,调用类的成员变量远远比查询数据库更加简单,编写的代码更少。

Ø        提高了设计的效率,只要在case studio(后面将详细介绍)中完成了数据库设计,就可以自动的生成数据库脚本、数据库设计文档、数据关系图、数据封装类,使快速程序设计成为可能。

 

但是,数据封装也存在一些缺点,它自动生成所有的数据表和视图的封装类,项目中包含很多类,查找一个类较为费时,另外编译的程序也较大。不过,在vc中可以利用字母索引查找各个类,或者在自动生成的类前面加前缀,基本不会影响它的易用性。

4.数据库的设计规范 4.1数据表的设计规范

要做数据封装,需要对数据表的设计做如下的规定:

1.        数据库的各个表格必须包含一个为number类型的Id字段,该字段唯一确定一条记录;

2.        该Id字段来自一个序列,假如表的名称为Yhxxb,该序列的名称为seq_yhxxb_id,CDataTable的Post函数中通过调用类似的语句select seq_yhxxb_id.nextval from dual找到新记录的Id。

3.        数据表之间的主外键关系需要建立,同时需要在数据库这一层来明确主键删除后子表如何处理,通过书写触发器来维护这些数据之间的关系。

4.        在数据库层要实现数据表的级联更新;

4.2视图的设计规范

视图的Sql语句的示范格式:

示例1:Create view abc(a,b,c,d) as select a , b ,(select y.cc from y where y.c=x.c) as c ,d from x;

示例2:create view abc as select x.a , x.b ,(select y.cc from y where y.c=x.c) as c ,z.d from x , z where x.c=z.c;

具体的要求说明如下:

1.      如果主select语句的from中有2个表,要按照示例2的规范来写,即select中的每个项目(如x.a)中指明是来自于哪个表的;

2.      视图的命名规则,主表名+”_v”;

3.      select查询中,只有具有子查询的项目才能够使用as;

4.      只支持最基本的查询,其它的查询如sum,count函数的视图,应该检查生成的类,并且手工修改出错的内容;

5.      视图中应该有一个Id字段,该字段是来自于主表的id字段;

6.      子查询中,应该保证中间没有”,”;

7.      如果在项目中没有写表名,如示例1,则主查询的from语句中只能有一个表;

8.      暂不支持表的别名如from a xxx,b yyy的查询;

9.      仅仅支持两级视图。

 

5.case studio的应用 5.1 Case Studio简介

Case Studio是捷克人设计的数据库开发利器,它的理念是Create database structures faster and easier越来越多的大公司和机构采用它,详情请参看http://www.casestudio.com。

 

该工具可以完成如下的功能:

Ø        进行可视化数据库设计,每一个Entity代表一个数据库表,可以快速的建立各种数据关系主外键等;

Ø        能够检查数据库设计的正确性;

Ø        自动生成详细的rtf或html格式的文档;

Ø        自动生成数据库创建的脚本;

Ø        支持脚本js或者vb脚本来访问各个Entity,本规范中生成C++类就是通过js脚本实现的;

Ø        能够把整个数据设计存储为Xml格式,可以书写其它程序来利用其数据;

Ø        能够从不同类型的数据库中解析出各个Entity;

Ø        支持多种数据库,并且能进行不同数据库的转换。

5.2 case studio中的脚本

支持js或vb脚本是该数据库工具的一个吸引人的地方,正是基于这一点,我们才能够轻松的生成基于自己规范的数据表和视图的封装类。下面简单介绍如何来书写脚本:

1)        点击按钮Edit Templates,打开模板编辑器。

2)        选择分支Events->User-defined system templates,点右键增加一个节点,按照如下图的内容来设置:

 

3)        在text页面输入你自己的js脚本,js脚本有固定的格式,必须有一个Main函数,详情可以在Case Studio的网站上下载示例程序,页面如下:

4)        重起case studio,就可以看到多了一个adds-in菜单,点击自定义函数的项目,就会弹出脚本的执行窗口,点击Run,会在Log里面生成程序输出的内容。

下面是利用该脚本生成的Yhxxb封装类:

class CYhxxb : public CDataTable

{

private:

                         ;//name      TypeName  TypeId    Length   

       CString  m_Yhm   ;//用户名     Varchar2   20         20     

       CString  m_Yhzwm ;//用户中文名 Varchar2   20         20      

       CString  m_Mm    ;//密码       Varchar2   20         20     

private:

       int C_Yhm      ;

       int C_Yhzwm    ;

       int C_Mm       ;

public:

       CYhxxb():CDataTable("Yhxxb")

       {

               C_Yhm = 20      ;

               C_Yhzwm = 20    ;

               C_Mm = 20       ;

              Find("");

       }

       ~CYhxxb()

       {

       }

       void FillAllFld()

       {

              BeginRead();

              SetYhm(GetFldAsCString("Yhm"));

              SetYhzwm(GetFldAsCString("Yhzwm"));

              SetMm(GetFldAsCString("Mm"));

              SetId(GetFldAsint("Id"));

              EndRead();

       }

       void SetFldDefault()

       {

              SetYhm("");

              SetYhzwm("");

              SetMm("");

       }

       CString GetYhm()

       {

              return m_Yhm;

       }

       void SetYhm(CString pi_Yhm)

       {

              CheckRecStatus(FALSE);

              if(pi_Yhm.GetLength()>C_Yhm)

              {

                     ThrowZhException("Yhm字段只能够接受小于20的字串!");

              }

              m_Yhm = pi_Yhm;

       }

.

.

.

};

6.总结

    本文介绍一种广泛的数据封装方法,它属于DIY的范畴,是一种框架设计,具有通用性,你所做的只是进行一次开发,尔后尽管到处引用。如何封装这些类,本文只是给出了较为简单的介绍,旨在抛砖引玉,你需要什么样的设计,马上行动吧!

本文地址:http://com.8s8s.com/it/it1504.htm