标题：数据访问对象
简介
DAO就是DatabaseAccess Objects，数据访问对象的英文缩写。在VB中提供了两种与Jet数据库引擎接口的方法：Data控件和数据访问对象（DAO）。Data控件只给出有限的不需编程而能访问现存数据库的功能，而DAO模型则是全面控制数据库的完整编程接口。Data控件将常用的DAO功能封装在其中，它与DAO控件的关系就好象内存与CACHE之间的关系一样，所以这两种方法并不是互斥的，实际上，它们常同时使用。
DAO数据访问对象（DataAccessObjects）是一种面向对象的界面接口。通过DAO/Jet功能可以访问ISAM数据库，使用DAO/ODBCDirect功能可以实现远程RDO功能。使用DAO的程序编码非常简单，DAO提供丰富的游标（Cursor）类型的结果集和非游标（Cursor-Less）类型的结果集，同DDL（数据描述语言）的功能很类似。现在vb数据库编程大都使用ADO，很少人还用DAO.
DAO是集合，对象，方法和属性；它用对象集合来处理数据库，表，视图和索引等。使用DAO编程，可以访问并操作数据库，管理数据库的对象和定义数据库的结构等。
DAO模型是设计关系数据库系统结构的对象类的集合。它们提供了完成管理一个关系型数据库系统所需的全部操作的属性和方法，这其中包括创建数据库，定义表、字段和索引，建立表间的关系，定位和查询数据库等。
Visual Basic中的数据库编程就是创建数据访问对象，这些数据访问对象对应于被访问物理数据库的不同部分，如数据库、表、字段和索引等，同时用这些对象的属性和方法来实现对数据库的操作，以便在Visual Basic窗体中使用绑定和非绑定控件来显示操作结果并接收用户输入。
识别数据库
Visual Basic通过DAO和Jet引擎可以识别三类数据库：VisualBasic数据库也就是*.MDB数据库外部数据库它们是使用几种流行格式的“索引顺序访问方法（ISAM）”数据库，这些流行格式包括Btrieve、dBASEIII、dBASEIV、Microsoft FoxPro versions2.0和2.5以及Paradox versions 3.x和4.0。在Visual Basic中能够创建和操作所有以上格式的数据库。也可以访问文本文件数据库和Microsoft Excel或Lotus1-2-3电子表格。ODBC数据库包括符合ODBC标准的客户/服务器数据库，如Microsoft SQL Server。要在Visual Basic中创建真正的客户/服务器应用程序，可以使用ODBC Direct直接把命令传递给服务器处理。也就是说Visual Basic还支持其它不使用Jet数据库引擎的数据访问方法。数据访问对象的ODBC Direct模式允许使用同样的对象模型和语法绕过Jet引擎直接访问ODBC数据。
由上面的叙述可知，对于编程人员来讲，你只须了解DAO的使用，对具体的数据库系统无须做深入的探讨，就可对几乎任何一种数据库进行操作，“以不便应万变”， 而对数据库文件自身的物理操作，将由相应的数据库引擎把数据访问对象上的这些操作转换为对数据库文件自身的物理操作，这些引擎来处理所有与各种数据库的接口。
结构
面向对象编程
大家对面向对象编程一定不陌生，但究竟什么是面向对象编程，很多人一下子也说不出个所以然来；在VB的DAO中又是如何体现面向对象的呢，恐怕即便是使用了一段VB的网友也很难说清。这也难怪，VB本身并不是个完全的面向对象的编程环境，它的很多如动态数组等就不是面向对象的，但在DAO中是完全的面向对象的。其实面向对象的最初思想就是将数据和操作封装在一起，形成对象，而在DAO中正是体现了这一点，它将数据的值作为属性，数据的查询作为方法，数据值的变化作为事件，完全封装在DAO对象中，希望诸位盟友在使用中注意，逐步领悟面向对象的编程方法。
数据库前端开发系统和后台系统 
经常由朋友说他会DELPHI，会PB，实际上用前端和后台的概念来看，他们都只是会一种前端开发工具而已，严格说起来并不能算会数据库的开发。人们往往只看到前台应用的功能而忽视了后台系统的应用，或者认为这两者根本就是一回事。前端后台概念用在单机上，就是VB与Access，用在网络中就是VB与SQL Sever，只会VB或DELPHI是不能称为掌握数据库编程的，而且在编程中，要善于利用后台数据库提供功能，这样的程序运行起来更快，程序更精练。
题外话讲完，现在切入正题。DAO的结构如图所示：
  DAO整体结构图以上是DAO整体结构图，下面将分章节逐步讲述每个对象的使用
数据访问对象DAO的功能
1. DAO用来封装Data Source的..就比如，Connection conn = DAOFacotry.createConnection()..就可以把Driver. URL. username,passpword这一些放在DAO中以后要更改数据库的类型.比如要把MSSQL换成Oracle的话..只需要更改DAOFacory里面的getConnection（）里面的Driver.URL.之类的..
2. DAO也是把对数据库的操作（比如最基本的CRUD操作）全部封装在里面..比如说你要你要插入一个新的用户..那么.在DAO中我们只需要提供一个insertUser(User user）这一个方法就可以了..具体的操作是在DAO中实现的...那么对于要调用DAO的时候.我们只要知道insertUser(User）是用来插入一个新的用户...而不需要知道是如何实现的..
一般 DAO是与Abstract Factory模式一起来用的...
Factory来建立数据库和定位具体的DAO（比如说是UserDao..CustomerDao..)..一般将getConnection设置为static..也可以把HibernateSessionFactory这一个公共类放在这一AbstractFactory类中去...
public class DAOFactory {private static final SessionFactory sessionFacotory;// 定义一个TrheadLocal .static Session currentSession().....public UserDao getUserDAO() { return new UserDaoImpl(sesssion);}pulbic OtherDao getOtherDAO() { return new OtherDaoImpl(session);}......}
public interface UserDao {public insertUser(FormBean) public updateUser(FormBean);}然后就实现DAO的接口： (Struts的FormBean...VO来的..)public class UserDaoImpl implements UserDao {privateSession session;public UserDaoImpl(Session session){this.session = session;}...public insertUser(FormBean) { ..//..session.save(UserPO);..//..return FormBean;}public FormBean updateUser(FormBean) {..//..session.update(UserPO);..//..return FormBean;}}最后定义你的PO:public class UserPO {String firstname,lastname,password..........}
Huhmmmm..........
实战应用
——使用数据访问对象DAO1 概述Visual C++提供了对DAO的封装，MFC DAO类封装了DAO（数据库访问对象）的大部分功能，从面Visual C++程序就可以使用Visual C++提供的MFC DAO类方便的访问Microsoft Jet 数据库，编制简洁、有Visaul C++特色的数据库应用程序。
数据库访问对象（DAO）提供了一种通过程序代码创建和操纵数据库的机制。多个DAO对象构成一个体系结构，在这个结构里，各个DAO对象协同工作。DAO支持以下四个数据库选项：
打开访问数据库（MDB文件）——MDB文件是一个自包含的数据库，它包括查询定义、安全信??须指定MDB文件的路径名。
直接打开ODBC数据源——这里有一个很重要的限制。不能找开以Jet引擎作为驱动程序的ODBC数据源；只可以使用具有自己的ODBC驱动程序DLL的数据源。
用Jet引擎找开ISAM型（索引顺序访问方法）数据源（包括dBase,FoxPro,Paradox,Btrieve,Excel或文本文件）——即使已经设置了ODBC数据源，要用Jet引擎来访问这些文件类型中的一种，也必须以ISAM型数据源的方式来找开文件，而不是以ODBC数据源的方式。
给ACCESS数据库附加外部表——这实际上是用DAO访问ODBC数据源的首选方法。首先使用ACCESS把ODBC表添加到一个MDB文件上，然后依照第一选项中介绍的方法用DAO找开这个MDB文件就可以了。用户也可以用ACCESS把IASM文件附加到一个MDB文件上。2 应用DAO编程2.1 打开数据库CDaoWorkspace对象代表一个DAO Workspace对象，在MFC DAO体系结构中处于最高处，定义了一个用户的同数据库的会话，并包含打开的数据库，负责完成数据库的事务处理。我们可以使用隐含的workspace对象。
CDaoDatabase对象代表了一个到数据库的连接，在MFC中，是通过CDaoDatabase封装的。
在构造CDaoDatabase对象时，有如下两种方法：
创建一个CDaoDatabase对象，并向其传递一个指向一个已经找开的CdaoWorkspace对象的指针。
创建一个CDaoDatabase对象，而不明确地指定使用的workspace，此时，MFC将创建一个新的临时的CDaoWorkspace对象。
如下代码所示：
CDaoDatabase db;
db.Open（“test.mdb”，FALSE,FALSE,_T（“”）；
其中参数一包括要打开的文件的全路径名。
2.2 查询记录一个DAO recordset对象，代表一个数据记录的集合，该集合是一个库表或者是一个查询的运行结果中的全部记录。CDaoRecorset对象有三种类型：表、动态集、快照。
通常情况下，我们在应用程序中可以使用CDaoRecordset的导出类，这一般是通过ClassWizard或AppWizard来生成的。但我们也可以直接使用CDaoRecordset类生成的对象。此时，我们可以动态地绑定recordset对象的数据成员。
如下代码所示：
COleVariant var;
long id;
CString str;
CDaoRecordset m_Set(&db);
m_Set.Open（“查询的SQL语句”）；
while(!m_Set.IsEOF())
{
/*
处理
m_Set.GetFieldValue（“ID”，var);
id=V_I4(var);
m_Set.GetFieldValue（“Name”，var);
str=var.pbVal;
*/
m_Set.MoveNext();
}
m_Set.Close();
2.3 添加记录
添加记录用AddNew函数，此时用SetFieldValue来进行赋值。
如下代码所示：
m_pDaoRecordset->AddNew ();
sprintf(strValue,"%s",>m_UserName );
m_pDaoRecordset->SetFieldValue ("UserName",strValue);
sprintf(strValue,"%d",m_PointId );
m_pDaoRecordset->SetFieldValue ("PointId",strValue);
dataSrc.SetDateTime (m_UpdateTime .GetYear ),m_UpdateTime .GetMonth ),m_UpdateTime .GetDay (),
m_UpdateTime .GetHour (),m_UpdateTime .GetMinute (),m_UpdateTime .GetSecond ());
valValue=dataSrc;
m_pDaoRecordset->SetFieldValue ("UpdateTime",valValue);
sprintf(strValue,"%f",m_pRecordset->m_OldValue );
m_pDaoRecordset->SetFieldValue ("OldValue",strValue);
sprintf(strValue,"%f",m_pRecordset->m_NewValue );
m_pDaoRecordset->SetFieldValue ("NewValue",strValue);
m_pDaoRecordset->Update ();
此时，要注意，日期时间型数据要用SetDataTime函数来赋值，这里面要用到COleVariant类型数据，具体用法可以参考有关帮助。
2.4 修改记录
修改记录用Edit（）函数，把记录定位到要修改的位置，调用Edit函数，修改完成后，调用Update函数。
如下代码所示：
m_Set.Edit();
m_Set.SetFieldValue（“列名”，”字符串”）；
m_Set.Update();
2.5 删除记录
删除记录用Delete（）函数，使用后不需调用Update（）函数。
2.6 统计记录
可以使用如下代码来统计记录数：
COleVariant varValue;
CDaoRecordset m_Set(&db);
m_Set.Open(dbOpenDynaset，”SQL语句”）；
varValue=m_Set.GetFieldValue(0);
m_lMaxCount=V_I4(&varValue);
m_Set.Close();
如果是统计一张表中总记录，可以使用CDaoTableDef对象，如下代码所示：
CDaoTableDef m_Set(&gUseDB);
Count=m_Set.GetRecordCount();
m_Set.Close();
不能用CDaoRecordset对象的GetRecordCount（）来取得记录数。3 总结使用DAO技术可以便我们方便的访问Microsoft Jet引擎数据库，由于Microsoft Jet不支持多线程，因此，必须限制调用到应用程序主线程的所有DAO。