chap06 数据库接口技术 - 数据库设计与实践

课程:0A102 数据库设计与实践(田浩然上传资料) 章节:第6章 数据库接口技术

概述

本章介绍了应用程序与数据库系统之间的接口技术,涵盖从底层C/C++接口到高层Web接口的多种数据库访问方式。主要内容包括:

  1. ODBC(开放式数据库连接) — 微软主导的数据库访问标准API
  2. JDBC(Java数据库连接) — Java平台的数据库访问标准
  3. PHP+MySQL — Web开发中最常用的数据库接口组合
  4. Web数据库接口技术 — CGI、ISAPI、NSAPI、ASP、ColdFusion等
  5. C/C++ ODBC编程实践 — 完整的ODBC API调用示例

一、ODBC(Open DataBase Connectivity)

1.1 ODBC概述

ODBC(开放式数据库连接) 是由 Microsoft 于 1991-1992 年提出的数据库访问标准,目的是提供一个统一的接口,使应用程序能够通过相同的API访问不同的数据库管理系统(DBMS)。

核心思想:应用程序只需要编写一套代码,通过ODBC驱动程序就可以访问Oracle、Sybase、Informix、Ingres、IBM DB/2、DEC RDB、HP ALLBASE/SQL、Gupta、Borland Paradox、dBase等多种数据库。

1.2 ODBC体系结构

应用程序
    ↓
ODBC API(应用程序接口)
    ↓
Driver Manager(驱动程序管理器)
    ↓
数据库驱动程序(Driver)
    ↓
数据库管理系统(DBMS)

组成部分:

组件作用
应用程序调用ODBC API,执行SQL语句,处理结果
Driver Manager管理驱动程序,加载/卸载驱动,路由调用
数据库驱动程序实现ODBC API,将标准调用转换为特定DBMS的调用
数据源(DSN)标识数据库连接信息(Data Source Name)

1.3 ODBC符合性级别

ODBC定义了驱动程序的符合性级别:

  • Core级别(核心级):最基本的ODBC功能
  • Level 1(一级):核心功能 + 更多函数
  • Level 2(二级):完整功能集

支持的数据库包括:Oracle、Sybase、Informix、DB2、SQL Server等主流RDBMS。

1.4 ODBC API核心函数

环境句柄(Environment Handle):

  • SQLAllocHandle(SQL_HANDLE_ENV, ...) — 分配环境句柄
  • SQLSetEnvAttr(..., SQL_ATTR_ODBC_VERSION, ...) — 设置ODBC版本
  • SQLFreeHandle(SQL_HANDLE_ENV, ...) — 释放环境句柄

连接句柄(Connection Handle):

  • SQLAllocHandle(SQL_HANDLE_DBC, ...) — 分配连接句柄
  • SQLConnect() — 连接数据源
  • SQLDisconnect() — 断开连接
  • SQLBrowseConnect() — 交互式连接

语句句柄(Statement Handle):

  • SQLAllocHandle(SQL_HANDLE_STMT, ...) — 分配语句句柄
  • SQLExecDirect() — 直接执行SQL语句
  • SQLPrepare() + SQLExecute() — 准备+执行(支持参数化)
  • SQLFreeStmt() — 释放语句句柄

结果集处理:

  • SQLFetch() — 获取一行数据
  • SQLBindCol() — 绑定列到变量
  • SQLGetData() — 获取列数据(不绑定)
  • SQLNumResultCols() — 获取结果列数
  • SQLDescribeCol() — 获取列描述信息
  • SQLExtendedFetch() — 扩展获取(滚动游标)

元数据获取:

  • SQLTables() — 获取表信息
  • SQLColumns() — 获取列信息
  • SQLStatistics() — 获取统计信息
  • SQLPrimaryKeys() — 获取主键信息
  • SQLForeignKeys() — 获取外键信息
  • SQLProcedures() — 获取存储过程信息
  • SQLGetTypeInfo() — 获取数据类型信息

其他:

  • SQLError() / SQLGetDiagRec() — 获取错误信息
  • SQLRowCount() — 获取受影响行数
  • SQLTransact() — 事务管理(提交/回滚)
  • SQLSetStmtOption() / SQLSetConnectOption() — 设置选项
  • SQLGetInfo() — 获取驱动程序/数据源信息
  • SQLGetFunctions() — 获取支持的函数列表
  • SQLCancel() — 取消正在执行的语句

1.5 C/C++ ODBC编程示例

完整的ODBC查询流程:

#include <sql.h>
#include <sqlext.h>
 
int main() {
    SQLHENV hEnv;          // 环境句柄
    SQLHDBC hConnect;      // 连接句柄
    SQLHSTMT hStmt;        // 语句句柄
    SQLRETURN r;           // 返回值
    SQLCHAR RetName[20];   // 结果缓冲区
    SQLLEN cbName;         // 实际长度
 
    // 1. 分配环境句柄
    r = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);
    if (r != SQL_SUCCESS) { /* 错误处理 */ }
 
    // 2. 设置ODBC版本
    r = SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION,
                      (void*)SQL_OV_ODBC3, 0);
    if (r == SQL_ERROR || r == SQL_SUCCESS_WITH_INFO) {
        // 错误处理
    }
 
    // 3. 分配连接句柄
    r = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hConnect);
 
    // 4. 连接数据源
    r = SQLConnect(hConnect,
                   (SQLCHAR*)"local", SQL_NTS,    // DSN
                   (SQLCHAR*)"username", SQL_NTS, // 用户名
                   (SQLCHAR*)"password", SQL_NTS); // 密码
    if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
        // 错误处理
    }
 
    // 5. 分配语句句柄
    r = SQLAllocHandle(SQL_HANDLE_STMT, hConnect, &hStmt);
 
    // 6. 执行SQL查询
    char SQLString[100];
    strcpy(SQLString, "select au_lname from authors");
    r = SQLExecDirect(hStmt, (SQLCHAR*)SQLString, strlen(SQLString));
    if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
        // 错误处理
    }
 
    // 7. 绑定列
    r = SQLBindCol(hStmt, 1, SQL_C_CHAR,
                   (SQLPOINTER)RetName, 20, &cbName);
 
    // 8. 逐行获取结果
    while (1) {
        r = SQLFetch(hStmt);
        if (r == SQL_NO_DATA) break;
        if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
            // 错误处理
            break;
        }
        cout << RetName << endl;
    }
 
    // 9. 清理资源
    SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
    SQLDisconnect(hConnect);
    SQLFreeHandle(SQL_HANDLE_DBC, hConnect);
    SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
 
    return 0;
}

ODBC编程要点:

  • 句柄管理遵循”先分配后释放”原则,顺序:环境→连接→语句,释放顺序相反
  • 返回值检查:SQL_SUCCESS、SQL_SUCCESS_WITH_INFO、SQL_ERROR、SQL_NO_DATA
  • 使用 SQL_NTS 表示字符串以null结尾(Null-Terminated String)
  • 绑定列后通过 SQLFetch 逐行读取,数据自动填入绑定的缓冲区

二、JDBC(Java Database Connectivity)

2.1 JDBC概述

JDBC 是Java语言的数据库访问标准API,由JavaSoft(Sun)定义,提供了一套与数据库无关的Java类和接口。

JDBC与ODBC的关系:

  • JDBC的设计参考了ODBC的思想
  • JDBC提供了JDBC-ODBC桥接驱动,可以通过ODBC访问数据库
  • JDBC是纯Java的,跨平台性更好

2.2 JDBC四种驱动类型

Type 1: JDBC-ODBC Bridge plus ODBC Driver(JDBC-ODBC桥接驱动)

Java应用 → JDBC API → JDBC-ODBC桥 → ODBC驱动 → 数据库
  • 特点:将JDBC调用转换为ODBC调用
  • 优点:可以利用已有的ODBC驱动
  • 缺点:性能较低,需要本地ODBC库,不是纯Java
  • 适用:快速原型开发、没有专用JDBC驱动的情况

Type 2: Native API partly Java technology-enabled driver(本地API部分Java驱动)

Java应用 → JDBC API → Java驱动(部分本地代码) → 数据库客户端库 → 数据库
  • 特点:调用数据库厂商提供的本地API(C/C++库)
  • 优点:比Type 1性能好
  • 缺点:需要安装数据库客户端软件,不是纯Java
  • 代表:Oracle OCI驱动

Type 3: Pure Java Driver for Database Middleware(纯Java中间件驱动)

Java应用 → JDBC API → 纯Java驱动 → 中间件服务器 → 数据库
  • 特点:通过网络协议与中间件通信,中间件再访问数据库
  • 优点:纯Java,客户端不需要数据库客户端
  • 缺点:需要中间件服务器,多了一层
  • 代表:WebLogic的t3协议、RMI-based驱动

Type 4: Direct-to-Database Pure Java Driver(直连数据库纯Java驱动)

Java应用 → JDBC API → 纯Java驱动(直接网络协议) → 数据库
  • 特点:直接使用数据库的网络协议,完全用Java实现
  • 优点:性能最好,纯Java,跨平台,不需要客户端软件
  • 缺点:每个数据库需要自己的驱动
  • 代表:Oracle Thin驱动、MySQL Connector/J

驱动选型原则:

  • 生产环境优先使用 Type 4(纯Java直连)
  • 开发/测试环境可用 Type 1(桥接)快速上手
  • Type 2 和 Type 3 在特定场景下使用

2.3 JDBC核心API

主要类和接口:

接口/类作用
DriverManager驱动程序管理器,管理注册的驱动
Connection数据库连接
StatementSQL语句执行对象(静态SQL)
PreparedStatement预编译SQL语句对象(参数化查询)
CallableStatement调用存储过程
ResultSet查询结果集
ResultSetMetaData结果集元数据
DatabaseMetaData数据库元数据

JDBC编程基本流程:

// 1. 加载并注册驱动 (JDBC 4.0以前需要)
Class.forName("com.mysql.jdbc.Driver");
Class.forName("oracle.jdbc.driver.OracleDriver");
 
// 2. 建立连接
String url = "jdbc:mysql://localhost:3306/dbname";
String user = "username";
String password = "password";
Connection conn = DriverManager.getConnection(url, user, password);
 
// 3. 创建语句对象
Statement stmt = conn.createStatement();
 
// 4. 执行SQL
ResultSet rs = stmt.executeQuery("SELECT * FROM table");
// 或者:int rows = stmt.executeUpdate("INSERT INTO ...");
 
// 5. 处理结果集
while (rs.next()) {
    int id = rs.getInt("id");
    String name = rs.getString("name");
    // ...
}
 
// 6. 关闭资源(顺序:ResultSet → Statement → Connection)
rs.close();
stmt.close();
conn.close();

2.4 JDBC-ODBC桥接

JDBC-ODBC桥(JDBC-ODBC Bridge)是JDK内置的驱动,允许Java程序通过ODBC访问数据库。

用法:

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection conn = DriverManager.getConnection(
    "jdbc:odbc:datasource_name", "user", "password");

注意: JDBC-ODBC桥在Java 8及以后版本中已被移除/废弃。

2.5 SQL/CLI标准

SQL/CLI(Call Level Interface,调用级接口)是SQL标准的一部分(SQL/CLI = SQL-99的第3部分),定义了数据库访问的API标准。ODBC和JDBC都遵循类似的CLI思想。


三、PHP数据库接口

3.1 PHP概述

PHP(Personal Home Page / PHP: Hypertext Preprocessor) 是一种广泛使用的服务器端脚本语言,特别适合Web开发。由 Rasmus Lerdorf 创建。

PHP支持几乎所有主流数据库:

  • MySQL / PostgreSQL
  • Oracle / SQL Server
  • ODBC 兼容数据库
  • SQLite / MongoDB 等

3.2 PHP+ODBC接口

PHP通过ODBC扩展可以访问任何支持ODBC的数据库。

常用ODBC函数:

函数作用
odbc_connect(dsn, user, password)连接数据源,返回连接标识
odbc_do(conn, query)执行SQL查询,返回结果集标识
odbc_exec(conn, query)同odbc_do,执行SQL
odbc_fetch_row(result)获取一行数据
odbc_result(result, field)获取指定字段的值
odbc_num_rows(result)获取结果行数
odbc_num_fields(result)获取结果列数
odbc_field_name(result, field_num)获取字段名
odbc_field_type(result, field_num)获取字段类型
odbc_close(conn)关闭连接

PHP ODBC编程示例:

<?php
// 连接数据源
$conn = odbc_connect("datasource_name", "username", "password");
 
if (!$conn) {
    die("连接失败: " . odbc_errormsg());
}
 
// 执行查询
$query = "SELECT * FROM table_name";
$result = odbc_do($conn, $query);
 
// 获取结果
while (odbc_fetch_row($result)) {
    $id = odbc_result($result, "id");
    $name = odbc_result($result, "name");
    echo "ID: $id, Name: $name<br>";
}
 
// 关闭连接
odbc_close($conn);
?>

3.3 PHP+MySQL

PHP+MySQL是Web开发中最经典的组合之一(LAMP = Linux + Apache + MySQL + PHP)。

MySQL函数(旧版mysql扩展,已废弃):

  • mysql_connect(host, user, password) — 连接MySQL
  • mysql_select_db(dbname) — 选择数据库
  • mysql_query(sql) — 执行查询
  • mysql_fetch_row(result) / mysql_fetch_array(result) — 获取行
  • mysql_close() — 关闭连接

注意: 旧版mysql扩展在PHP 5.5中被废弃,PHP 7中已移除。应使用MySQLi(面向对象/过程)或PDO扩展。


四、Web数据库接口技术

4.1 Web数据库访问模式

客户端浏览器
    ↓ HTTP
Web服务器
    ↓ 接口技术
数据库服务器

Web环境下的数据库访问特点:

  • 无状态协议(HTTP)
  • 多用户并发访问
  • 通过Web服务器作为中间层

4.2 CGI(Common Gateway Interface)

CGI(通用网关接口) 是最早的Web服务器与外部程序交互的标准。

工作原理:

  1. 浏览器发送HTTP请求到Web服务器
  2. Web服务器启动CGI程序(每次请求一个进程)
  3. CGI程序读取环境变量和标准输入,处理请求
  4. CGI程序访问数据库,生成HTML
  5. 输出通过标准输出返回给Web服务器,再返回浏览器

特点:

  • 优点:简单、语言无关(C/C++、Perl、Shell等都可以)
  • 缺点:每次请求创建新进程,性能差,资源消耗大

4.3 ISAPI / NSAPI

ISAPI(Internet Server API) — Microsoft IIS的扩展接口 NSAPI(Netscape Server API) — Netscape服务器的扩展接口

特点:

  • 以动态链接库(DLL)形式加载到Web服务器进程中
  • 比CGI性能好(进程内调用,无需创建新进程)
  • 缺点:开发复杂,一个模块崩溃可能影响整个服务器

4.4 ASP(Active Server Pages)

ASP 是Microsoft推出的服务器端脚本技术,运行在IIS上。

特点:

  • 支持VBScript、Perl、Python等脚本语言
  • 通过ADO(ActiveX Data Objects)访问数据库
  • 与Windows/IIS深度集成
  • 已被ASP.NET取代

ASP访问数据库示例:

<%
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "DSN=database;UID=user;PWD=password"
Set rs = conn.Execute("SELECT * FROM table")
While Not rs.EOF
    Response.Write rs("column_name") & "<br>"
    rs.MoveNext
Wend
rs.Close
conn.Close
%>

4.5 ColdFusion

ColdFusion 是Allaire(后被Macromedia/Adobe收购)开发的快速Web应用开发平台。

特点:

  • 使用CFML(ColdFusion Markup Language)标记语言
  • 数据库访问简单,标签化(<cfquery>、<cfoutput>等)
  • 管理界面:ColdFusion Administrator
  • 适合快速开发数据驱动的Web应用

ColdFusion示例:

<cfquery name="myQuery" datasource="myDSN">
    SELECT * FROM table_name
</cfquery>
 
<cfoutput query="myQuery">
    #column_name#<br>
</cfoutput>

4.6 ADO(ActiveX Data Objects)

ADO 是Microsoft的高层数据库访问组件,基于OLE DB。

ADO对象模型:

  • Connection — 数据库连接
  • Command — 命令对象
  • Recordset — 记录集(结果集)
  • Field — 字段
  • Parameter — 参数
  • Property — 属性

ADO与ODBC/OLE DB的关系:

ADO → OLE DB Provider → ODBC Driver → 数据库
      (或直接访问)

4.7 OLE DB

OLE DB 是Microsoft的底层数据访问接口,比ODBC更通用,不仅可以访问关系数据库,还可以访问非关系数据源(Excel、文本文件、目录服务等)。


五、数据库接口技术对比

5.1 各种接口比较

接口技术语言/平台跨平台性能易用性典型应用场景
ODBCC/C++Windows为主,Unix有unixODBC高较低底层系统编程
JDBCJava完全跨平台中→高(Type4)中Java企业应用
PHPPHP跨平台中高Web应用开发
ASP/ADOVBScript等Windows中高Windows Web应用
ColdFusionCFML跨平台中很高快速Web开发
CGI任意跨平台低低早期Web应用

5.2 选型建议

  • Java应用 → 首选JDBC(Type 4驱动)
  • PHP Web应用 → 首选PDO或mysqli
  • Windows/.NET应用 → ADO.NET
  • C/C++高性能应用 → 原生API或ODBC
  • 快速原型/低代码 → ColdFusion等RAD工具

六、本章知识图谱

数据库接口技术
├── ODBC (开放式数据库连接)
│   ├── 体系结构:应用程序 → Driver Manager → Driver → DBMS
│   ├── 符合性级别:Core / Level 1 / Level 2
│   ├── 核心API
│   │   ├── 环境:SQLAllocHandle, SQLSetEnvAttr
│   │   ├── 连接:SQLConnect, SQLDisconnect
│   │   ├── 语句:SQLExecDirect, SQLPrepare/Execute
│   │   ├── 结果:SQLFetch, SQLBindCol, SQLGetData
│   │   └── 元数据:SQLTables, SQLColumns, SQLStatistics
│   └── C/C++编程:句柄管理 → 连接 → 执行 → 结果处理 → 清理
├── JDBC (Java数据库连接)
│   ├── 四种驱动类型
│   │   ├── Type 1: JDBC-ODBC桥
│   │   ├── Type 2: 本地API + Java
│   │   ├── Type 3: 中间件协议纯Java
│   │   └── Type 4: 直连纯Java(推荐)
│   ├── 核心类:DriverManager, Connection, Statement, ResultSet
│   ├── 编程流程:加载驱动 → 建连接 → 执行SQL → 处理结果 → 关闭
│   └── SQL/CLI标准
├── PHP数据库接口
│   ├── PHP+ODBC:odbc_connect, odbc_do, odbc_fetch_row, odbc_result
│   ├── PHP+MySQL:mysql扩展(已废弃,推荐MySQLi/PDO)
│   └── LAMP架构
└── Web数据库接口
    ├── CGI — 通用网关接口(性能低)
    ├── ISAPI/NSAPI — 服务器API(进程内,性能好)
    ├── ASP + ADO — Microsoft平台
    ├── ColdFusion — 快速开发,CFML标记语言
    ├── ADO对象模型:Connection, Command, Recordset
    └── OLE DB — 通用数据访问底层接口

关联笔记

来源:田浩然上传的资料/0A102 数据库设计与实践/chap06 数据库接口技术.ppt 提取方式:PowerPoint二进制TextCharsAtom记录提取(图片型PPT,文本部分提取)