1 / 37

常用的数据库连接技术

常用的数据库连接技术. Windows 下. ODBC. OLE DB. ADO. 1. 史 前. 对数据库的访问通过本机库执行 SQL Server 的 DBLit Oracle 的 OCI ( Oracle Call Interface ) 保证快速访问(不涉及到中间层) 但开发人员需要通过不同的 API 来访问不同的数据库 一旦更换数据库,程序修改麻烦. 2. ODBC. 开放 数据库互连( ODBC )是 MICROSOFT 提出的数据库访问接口 标准 ODBC 提供 了一种标准的 API 方法 来 访问 DBMS 。 查看 MSDN

morrie
Download Presentation

常用的数据库连接技术

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 常用的数据库连接技术

  2. Windows下 ODBC OLE DB ADO

  3. 1. 史前 • 对数据库的访问通过本机库执行 • SQL Server的DBLit • Oracle的OCI(Oracle Call Interface) • 保证快速访问(不涉及到中间层) • 但开发人员需要通过不同的API来访问不同的数据库 • 一旦更换数据库,程序修改麻烦

  4. 2. ODBC • 开放数据库互连(ODBC)是MICROSOFT提出的数据库访问接口标准 • ODBC提供了一种标准的API方法来访问DBMS。 • 查看MSDN • 而不是数据库厂商的手册 • ODBC的设计者们努力使它具有 最大的独立性和开放性:与具体的编程语言无关,与具体的数据库系统无关,与具体的操作系统无关。 • ODBC API利用SQL完成大部分任务

  5. 2. ODBC续

  6. 3. OLE DB • 直接通过ODBC API编写应用程序相当复杂 • ODBC只能访问关系数据库 • OLEDB(Object Linking and Embedding, Database, 又称为OLE DB或OLE-DB),能提供对所有类型的数据的操作,包括关系数据库与非关系数据库(如EXCEL与HTML文件) • 作为微软的组件对象模型(COM)的一种设计,OLE DB是一组读写数据的方法

  7. 3. OLE DB续 • OLE DB是在一切对象化的趋势下,微软打算用它取代ODBC • 直接的OLEDB,每个数据库产品提供类似ODBC的驱动程序,称为OLEDB Provider • 面向ODBC的OLEDB,架构在ODBC上,这样没有自己的OLEDB提供者的数据库也可以使用OLEDB的特点了。 • OLEDB的效率要高于ODBC,而且OLEDB要包含ODBC。

  8. 4. ADO • ADO是OLE DB API的简化版本,实际上是位于OLE DB API顶部的附加层。将OLEDB中的许多概念封装,是对OLEDB模型的一种改进。 • OLE DB是一系列API,使用时需要按特定顺序进行许多不同的API调用。 • ADO是面向对象的API,只要操作几个对象的属性和方法即可

  9. 5. 三种方法的关系 ADO OLE DB ODBC JET SQL ORACLE JET SQL ORACLE ACCESS SQL SERVER ORACLE ACCESS SQL SERVER ORACLE

  10. 6. ADO中的对象 • ADO对象模型定义了一个可编程的分层对象集合,主要由三个对象成员Connection、Command和Recordset对象,以及几个集合对象Errors、Parameters和Fields等所组成。

  11. ADO对象描述 • 对象名 描 述 • Connection 指定连接数据来源 • Command 发出命令信息从数据源获取所需数据 • Recordset由一组记录组成的记录集 • Error 访问数据源时所返回的错误信息 • Parameter 与命令对象有关的参数 • Field 记录集中某个字段的信息

  12. 使用ADO编程 • (1)初始化COM库,引入ADO库定义文件 • (2)用Connection对象连接数据库 • (3)利用建立好的连接,通过Connection、Command对象执行SQL命令,或利用Recordset对象取得结果记录集进行查询、处理。 • (4)使用完毕后关闭连接释放对象。

  13. [1]COM初始化 • 我们可以使用AfxOleInit()来初始化COM库,这项工作通常在CWinApp::InitInstance()的重载函数中完成,请看如下代码:  BOOL CADOTest1App::InitInstance()    {  AfxOleInit();    ...... 

  14. [2]用#import指令引入ADO类型库  • 在stdafx.h中加入如下语句:#import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename ("EOF","adoEOF")  • 其最终作用同我们熟悉的#include类似。 • 几点说明:  (1) msado15.dll所在的目录(2) 在编译的时候肯能会出现如下警告,对此微软在MSDN中作了说明,并建议我们不要理会这个警告。  msado15.tlh(405) : warning C4146: unary minus operator applied to unsigned type, result 

  15. [3]创建Connection对象并连接数据库 • 创建Connection对象并连接数据库 • _ConnectionPtrm_pConnection; • HRESULT hr;  try{hr = m_pConnection.CreateInstance(“ADODB.Connection”); if(SUCCEEDED(hr))  {  hr = m_pConnection->Open(“STRING”,“”,“”,adModeUnknown); }}catch(_com_error e)///捕捉异常  {CStringerrormessage;  errormessage.Format("连接数据库失败!\r\n错误信息:%s", e.ErrorMessage());  AfxMessageBox(errormessage);///显示错误信息  } 

  16. 连接数据库 • HRESULT Connection15::Open ( _bstr_tConnectionString, _bstr_tUserID, _bstr_t Password, long Options ) • ConnectionString为连接字串,UserID是用户名, Password是登陆密码,Options是连接选项,用于指定 • Connection对象对数据的更新许可权, • Options可以是如下几个常量: • adModeUnknown:缺省。当前的许可权未设置 • adModeRead:只读 • adModeWrite:只写 • adModeReadWrite:可以读写 • adModeShareDenyRead:阻止其它Connection对象以读权限打开连接 • adModeShareDenyWrite:阻止其它Connection对象以写权限打开连接 • adModeShareExclusive:阻止其它Connection对象打开连接 • adModeShareDenyNone:允许其它程序或对象以任何权限建立连接

  17. 常用的连接方式 • (1)通过JET数据库引擎对ACCESS2000数据库的连接 m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\test.mdb","","",adModeUnknown); • (2)通过DSN数据源对任何支持ODBC的数据库进行连接: m_pConnection->Open("Data Source=adotest; UID=sa;PWD=;","","",adModeUnknown); • (3)不通过DSN对SQL SERVER数据库进行连接: m_pConnection->Open("driver={SQL Server}; Server=127.0.0.1; DATABASE=vckbase; UID=sa;PWD=139", "","",adModeUnknown); 其中Server是SQL服务器的名称,DATABASE是库的名称

  18. Connection对象两个属性 • ConnectionTimeOutConnectionTimeOut用来设置连接的超时时间,需要在Open之前调用,例如: m_pConnection->ConnectionTimeout = 5;///设置超时时间为5秒  • State指明当前Connection对象的状态,0表示关闭,1表示已经打开,我们可以通过读取这个属性来作相应的处理,例如:  if(m_pConnection->State)  m_pConnection->Close(); ///如果已经打开了连接则关闭它 

  19. [4].执行SQL命令并取得结果记录集 • 为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtrm_pRecordset; • 并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset"); • SQL命令的执行可以采用多种形式,下面我们一进行阐述。

  20. 利用Connection对象的Execute方法执行SQL命令 • Execute方法的原型如下所示: • _RecordsetPtr Connection15::Execute ( _bstr_tCommandText, VARIANT * RecordsAffected, long Options ) 其中CommandText是命令字串,通常是SQL命令。参数RecordsAffected是操作完成后所影响的行数, 参数Options表示CommandText中内容的类型,Options可以取如下值之一: • adCmdText:表明CommandText是文本命令 • adCmdTable:表明CommandText是一个表名 • adCmdProc:表明CommandText是一个存储过程 • adCmdUnknown:未知 • Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。

  21. _variant_tRecordsAffected; ///执行SQL命令:CREATE TABLE创建表格users, users包含四个字段:整形ID,字符串username,整形old, 日期型birthday m_pConnection->Execute("CREATE TABLE users(ID INTEGER,usernameTEXT,oldINTEGER,birthdayDATETIME)",&RecordsAffected,adCmdText); ///往表格里面添加记录 m_pConnection->Execute(“INSERT INTO users(ID,username,old,birthday) valueS (1, “Washington”, 25, “1970/1/1”),&RecordsAffected, adCmdText); ///将所有记录old字段的值加一 m_pConnection->Execute("UPDATE users SET old = old+1", &RecordsAffected, adCmdText); ///执行SQL统计命令得到包含记录条数的记录集 m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users", &RecordsAffected,adCmdText); _variant_tvIndex = (long)0; _variant_tvCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量 m_pRecordset->Close();///关闭记录集 CString message; message.Format("共有%d条记录",vCount.lVal); AfxMessageBox(message);///显示当前记录条数

  22. 利用Command对象来执行SQL命令 _CommandPtrm_pCommand; m_pCommand.CreateInstance("ADODB.Command"); _variant_tvNULL; vNULL.vt = VT_ERROR; vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数 m_pCommand->ActiveConnection = m_pConnection; ///非常关键的一句,将建立的连接赋值给它 m_pCommand->CommandText = "SELECT * FROM users";///命令字串 m_pRecordset = m_pCommand->Execute (&vNULL,&vNULL,adCmdText);///执行命令,取得记录集

  23. 直接用Recordset对象进行查询取得记录集 m_pRecordset->Open("SELECT * FROM users",_variant_t((IDispatch*) m_pConnection,true), adOpenStatic,adLockOptimistic,adCmdText);

  24. Open方法的原型 HRESULT Recordset15::Open ( const _variant_t & Source, const _variant_t & ActiveConnection, enumCursorTypeEnumCursorType, enumLockTypeEnumLockType, long Options ) 其中: ①Source是数据查询字符串 ②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象) ③CursorType光标类型,它可以是以下值之一,请看这个枚举结构: enumCursorTypeEnum { adOpenUnspecified = -1,///不作特别指定 adOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark, RecordCount, AbsolutePosition, AbsolutePage都不能使用 adOpenKeyset= 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。 adOpenDynamic= 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。 adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。 };

  25. Open方法的原型 续 ④LockType锁定类型,它可以是以下值之一,请看如下枚举结构: enumLockTypeEnum { adLockUnspecified = -1,///未指定 adLockReadOnly = 1,///只读记录集 adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制 adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作 adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。 }; ⑤Options参考Connection对象的Execute方法的介绍

  26. [5].记录集的遍历、更新  • 根据我们刚才通过执行SQL命令建立好的users表,它包含四个字段:ID, username, old, birthday以下的代码实现:打开记录集,遍历所有记录,删除第一条记录,添加三条记录,移动光标到第二条记录,更改其年龄,保存到数据库。

  27. _variant_tvUsername,vBirthday,vID,vOld; _RecordsetPtrm_pRecordset; m_pRecordset.CreateInstance("ADODB.Recordset"); m_pRecordset->Open(“SELECT * FROM users”,_variant_t((IDispatch*), m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText); while(!m_pRecordset->adoEOF)///这里为什么是adoEOF而不是EOF呢?还记得rename("EOF","adoEOF")这一句吗? { vID = m_pRecordset->GetCollect(_variant_t((long)0));///取得第1列的值,从0开始计数,你也可以直接给出列的名称,如下一行 vUsername = m_pRecordset->GetCollect("username");///取得username字段的值 vOld = m_pRecordset->GetCollect("old"); vBirthday = m_pRecordset->GetCollect("birthday"); ///在DEBUG方式下的OUTPUT窗口输出记录集中的记录 if(vID.vt != VT_NULL && vUsername.vt != VT_NULL && vOld.vt != VT_NULL && vBirthday.vt != VT_NULL) TRACE("id:%d,姓名:%s,年龄:%d,生日:%s\r\n",vID.lVal,(LPCTSTR)(_bstr_t)vUsername,vOld.lVal, (LPCTSTR)(_bstr_t)vBirthday); m_pRecordset->MoveNext();///移到下一条记录 }

  28. m_pRecordset->MoveFirst();///移到首条记录 m_pRecordset->Delete(adAffectCurrent);///删除当前记录 ///添加三条新记录并赋值 for(int i=0;i<3;i++) { m_pRecordset->AddNew();///添加新记录 m_pRecordset->PutCollect("ID",_variant_t((long)(i+10))); m_pRecordset->PutCollect("username",_variant_t("叶利钦")); m_pRecordset->PutCollect("old",_variant_t((long)71)); m_pRecordset->PutCollect("birthday",_variant_t("1930-3-15")); } m_pRecordset->Move(1, _variant_t((long) adBookmarkFirst));///从第一条记录往下移动一条记录,即移动到第二条记录处 m_pRecordset->PutCollect( _variant_t("old"), _variant_t((long)45));///修改其年龄 m_pRecordset->Update();///保存到库中

  29. [6].关闭记录集与连接 记录集或连接都可以用Close方法来关闭  m_pRecordset->Close();///关闭记录集  m_pConnection->Close();///关闭连接 

  30. 服务器环境下的SQL • 三层体系结构 Web服务器 应用服务器 数据库服务器

  31. 流行的WEB数据库技术 • 跨平台的WEB数据库技术 Apache PHP引擎 MySQL数据库

  32. PHP访问数据库步骤 • 用户的浏览器发出HTTP请求(一个PHP文件),请求特定页面; • Web服务器收到请求,获取该文件,将其传至PHP引擎,要求其处理 • PHP引擎解析脚本。处理连接数据库命令,执行查询。连接数据库发送适当的查询; • MySQL接受查询并处理,将结果返回给PHP引擎; • PHP将查询结果格式化成HTML格式返回到Web服务器; • Web服务器将HTML页面数据发送到浏览器客户端。

  33. 1. PHP建立一个MySQL连接 • mysql_connect • mysql_connect(主机, 用户名, 密码) • 如果成功返回一个连接标识 • 失败返回FALSE • 主机可以带一个端口号如localhost:3306

  34. 2. 选择数据库 • mysql_select_db • boolmysql_select_db(数据库名[, 连接标识符]) • 成功返回TRUE • 失败返回FALSE • 如果没有指定连接标识符,选择上次打开的连接

  35. 2. 发送SQL语句到数据库 • mysql_query • mysql_query(SQL语句 [, 连接标识符]) • 成功返回执行结果 • 失败返回FALSE • 如果没有指定连接标识符,选择上次打开的连接

  36. 4. 检索查询结果 • mysql_fetch_row • array mysql_fetch_row(resourse result) • 返回根据所取得的行生成的数组 • 如果到达最后一行,返回FALSE

  37. 5.

More Related