什么是DAO

10.8.1 什么是DAO

  DAO(Database Access Object)使用Microsoft Jet数据库引擎来访问数据库。
Microsoft Jet为象Access和Visual Basic这样的产品提供了数据引擎。

  与ODBC一样,DAO提供了一组API供编程使用。MFC也提供了一组DAO类,封装了
底层的API,从而大大简化了程序的开发。利用MFC的DAO类,用户可以编写独立于
DBMS的应用程序。

  DAO是从Visual C++4.0版开始引入的。一般地讲,DAO类提供了比ODBC类更广
泛的支持。一方面,只要有ODBC驱动程序,使用Microsoft Jet的DAO就可以访问
ODBC数据源。另一方面,由于DAO是基于Microsoft Jet引擎的,因而在访问
Access数据库(即*.MDB文件)时具有很好的性能。

10.8.2 DAO和ODBC的相似之处

DAO类与ODBC类相比具有很多相似之处,这主要有下面几点:

二者都支持对各种ODBC数据源的访问。虽然二者使用的数据引擎不同,但都可以满
足用户编写独立于DBMS的应用程序的要求。

DAO提供了与ODBC功能相似的MFC类。例如,DAO的CDaoDatabase类对应ODBC的
CDatabase类,CDaoRecordset对应CRecordset,CDaoRecordView对应CRecordView
,CDaoException对应CDBException。这些对应的类功能相似,它们的大部分成员
函数都是相同的。

AppWizard和ClassWizard对使用DAO和ODBC对象的应用程序提供了类似的支持。

  由于DAO和ODBC类的许多方面都比较相似,因此只要用户掌握了ODBC,就很容
易学会使用DAO。实际上,用户可以很轻松地把数据库应用程序从ODBC移植到DAO。


  Visual C++随盘提供了一个名为DaoEnrol的例子,该例实际上是Enroll的一个
DAO版本。读者可以打开DaoEnrol工程看一看,它的源代码与Enroll的极为相似。
读者可以按照建立Enroll的步骤来建立DaoEnrol,其中只有若干个地方有差别,这
主要有以下几点:

选取的数据源不同。在用AppWizard创建DaoEnrol时,以及在用ClassWizard创建
CDaoRecordset类的派生类时,在Database Options对话框中应该选择DAO而不是
ODBC。而且DAO的数据源是通过选择一个.MDB文件来指定的,即点击“...”按钮后
在文件对话框中选择要访问的.MDB文件。

记录集的缺省类型不同。ODBC记录集的缺省类型是快照(Snapshot),而DAO则是动
态集(Dynaset)。

参数化的方式不同。DAO记录集的m_strFilter和m_strSort中的参数不是“?”号,
而是一个有意义的参数名。例如,在下面的过滤器中有一个名为CourseIDParam的
参数。
m_pSet->m_strFilter ="CourseID = CourseIDParam";
在DoFieldExchange函数中,有下面两行:
pFX->SetFieldType(CDaoFieldExchange::param);
DFX_Text(pFX, _T("CourseIDParam"), m_strCourseIDParam);
DFX函数的第二个参数也是CourseIDParam。

处理异常的方式不同。例如,在删除记录时,对异常的处理如下所示:

try

{

m_pSet->Delete();

}

catch(CDaoException* e)

{

AfxMessageBox(e->

m_pErrorInfo->m_strDescription);

e->Delete();

}

  除了上述差别外,AppWizard和ClassWizard也隐藏了一些细微的不同之处,例
如,DAO记录集是使用是DFX数据交换机制(DAO record field exchange)而不是
RFX,在DAO记录集的DoFieldExchange中使用的是DFX函数而不是RFX函数。

10.8.3 DAO的特色

  DAO可以通过ODBC驱动程序访问ODBC数据源。但DAO是基于Microsoft Jet引擎
的,通过该引擎,DAO可以直接访问Access、FoxPro、dBASE、Paradox、Excel和
Lotus WK等数据库。CDaoDatabase类可以直接与这些数据库进行连接,而不必在
ODBC管理器中注册DSN。例如,下面的代码用来打开一个FoxPro数据库:

CDaoDatabase daoDb;

daoDb.Open( “”,FALSE,FALSE,"FoxPro 2.5;DATABASE=c://zyf");

CDaoDatabase::Open函数用来连接某个数据库,该函数的声明为:

virtual void Open( LPCTSTR lpszName, BOOL bExclusive = FALSE, BOOL
bReadOnly = FALSE, LPCTSTR lpszConnect = _T("") );
throw( CDaoException, CMemoryException );

 

  参数bExclusive如果为TRUE,则函数以独占方式打开数据库,否则就用共享方
式。如果bReadOnly为TRUE,那么就以只读方式打开数据库。如果要打开一个
Access数据库,则可以在lpszName参数中指定MDB文件名。如果要访问非Access数
据库,则应使该参数为“”,并在lpszConnect中说明一个连接字符串。连接字符
串的形式一般为 “数据库类型;DATABASE=路径(文件)”,例如 “dBASE III;
DATABASE=c://MYDIR”

  Open函数也可以打开一个ODBC数据源,但这需要相应的ODBC驱动程序,并需要
在ODBC管理器中注册DSN。此时lpszConnect的形式为 “ODBC;DSN=MyDataSource”
。显然,用DAO访问象FoxPro这样的数据库时,直接打开比把它当作ODBC数据源打
开要省事。

  支持DDL是DAO对数据库编程良好支持的一个重要体现。DDL(Data
Definition Language)在SQL术语中叫做“数据定义语言”,它用来完成生成、修
改和删除数据库结构的操作。ODBC类只支持DML(Data Manipulation Language,数
据操作语言),不支持DDL,所以用ODBC类只能完成数据的操作,不能涉及数据库的
结构。要执行DDL操作,只有通过ODBC API。而DAO类同时提供了对DML和DDL的支持
,这意味着程序可以使用DAO类方便的创建数据库及修改数据库的结构。

  与ODBC相比,DAO提供了一些新类来加强其功能,这些新类包括:

CDaoTableDef类提供了对表的结构的定义。调用CDaoTableDef::Open可以获得表的
结构定义。调用CDaoTableDef::Create可以创建一张新表,调用CDaoTableDef::
CreateField可为表添加字段,调用CDaoTableDef::CreateIndex可以为表添加索引
。调用CDaoTableDef::Append可以把新创建的表保存到数据库中。

CDaoQueryDef类代表一个查询定义(Query definition),该定义可以被存储到数据
库中。

CDaoWorkspace提供了数据工作区(Workspace)。一个工作区可以包含几个数据库,
工作区可以对所属的数据库进行全体或单独的事务处理,工作区也负责数据库的安
全性。如果需要,程序可以打开多个工作区。

  DAO的另一个重要特色在于它对Access数据库提供了强大的支持。由于DAO是基
于Microsoft Jet引擎的,所以DAO肯定要在Access数据库上多作一些文章。例如,
调用CDaoDatabase::Create可以直接建立一个MDB文件,代码如下所示:
m_db.Create(“C://MYDIR//MYDB.MDB”);

利用AppWizard和ClassWizard,用户可以方便地开发出性能优良的基于DAO的
Access数据库应用程序。

10.8.4 ODBC还是DAO

由于DAO可以访问ODBC数据源,下面几条可以作为DAO替代ODBC的理由:

在某些情况下可以获得更好的性能,特别是在访问Microsoft Jet(.MDB)数据库
时。

与ODBC兼容

DAO允许数据有效检查

DAO允许用户说明表与表之间的关系

  当然,DAO的出现并不意味着ODBC已经过时了。如果用户的工作必须严格限于
ODBC数据源,尤其是在开发Client/Server结构的应用程序时,用ODBC有较好的性
能。
 
### DAO类的概念及用途 #### 什么是DAO类? 数据访问对象(Data Access Object,简称DAO)是一种设计模式,主要用于封装对底层数据源的操作。通过这种模式,应用程序能够以一种统一的方式与不同的数据存储机制进行交互[^1]。 DAO的主要职责是对数据库或其他持久化存储介质进行读写操作,并将这些操作隐藏在一个抽象层之后。这样做的好处是可以使业务逻辑层专注于处理核心功能,而无需关心具体的数据库细节[^2]。 #### DAO的设计原则 DAO模式通常遵循以下几个基本原则: - **单一职责**:每个DAO类只负责一个特定类型的实体或表的相关操作。 - **接口定义**:为每种数据访问需求定义清晰的接口,使得调用者只需知道如何使用接口即可。 - **解耦合**:将数据访问逻辑从业务逻辑中分离出来,从而提高系统的可维护性扩展性[^3]。 --- ### 数据访问对象模式的实现方式 #### 基本结构 DAO模式一般由以下几部分组成: 1. **模型对象/数值对象 (VO)** 这是一个简单的Java Bean或者POJO(Plain Old Java Object),用于表示从数据库中检索出来的数据记录。它主要包含属性以及对应的gettersetter方法。 ```java public class Student { private int id; private String name; // Getter and Setter methods public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } ``` 2. **DAO接口** 定义了一组标准的方法来描述针对某个具体实体所能执行的操作,比如增删改查等基本功能[^4]。 ```java public interface StudentDAO { List<Student> getAllStudents(); Student getStudentById(int id); void addStudent(Student student); void updateStudent(Student student); void deleteStudent(int id); } ``` 3. **DAO实现类** 提供实际的功能实现,内部会涉及到JDBC或者其他ORM框架的具体编码工作。 ```java import java.sql.*; import java.util.ArrayList; import java.util.List; public class StudentDAOImpl implements StudentDAO { @Override public List<Student> getAllStudents() throws SQLException { Connection conn = null; Statement stmt = null; ResultSet rs = null; try { conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/school", "root", ""); stmt = conn.createStatement(); rs = stmt.executeQuery("SELECT * FROM students"); List<Student> list = new ArrayList<>(); while (rs.next()) { Student s = new Student(); s.setId(rs.getInt("id")); s.setName(rs.getString("name")); list.add(s); } return list; } finally { if (rs != null) rs.close(); if (stmt != null) stmt.close(); if (conn != null) conn.close(); } } @Override public Student getStudentById(int id) throws SQLException { // Implementation omitted for brevity. return null; } @Override public void addStudent(Student student) throws SQLException { // Implementation omitted for brevity. } @Override public void updateStudent(Student student) throws SQLException { // Implementation omitted for brevity. } @Override public void deleteStudent(int id) throws SQLException { // Implementation omitted for brevity. } } ``` --- ### 使用场景与优势分析 #### 应用场景 当项目需要频繁地同多种不同形式的数据源打交道时,采用DAO模式是非常合适的解决方案之一。无论是传统的RDBMS还是现代NoSQL数据库,都可以借助该模式轻松切换并保持原有架构不变。 #### 主要优点 - **降低复杂度**:把复杂的SQL语句集中到一处管理,便于调试优化性能。 - **增强灵活性**:如果未来更换了新的数据库管理系统,则只需要修改相应的DAO实现而不影响其他模块。 - **促进重用**:公共的服务函数可以在多个地方共享,减少重复劳动量的同时也提升了代码质量。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值