使用 ASP.NET 技术实现 BLOB 类型数据存取的研究 陈少平, 方子帆, 舒文辉三峡大学机械与材料学院, 湖北宜昌 (443002) E-mail:fzf@ctgu.edu.cn 摘要 : 通过对 ADO.NET 技术的数据模型分析研究与特点概述, 提出了对数据库中 BLOB 类型的数据进行存取的实现方法 结合具体实例, 说明在 Web 数据库系统中, 如何运用 ASP.NET 技术实现 Oracle 10g 数据库对图片 声音 视频及各种 Office 文档等进行存储并通过浏览器进行显示 该实例采用 C# 编程语言实现, 为数据库中多种二进制大对象类型的数据的存储和显示提供了一种可行有效的方法, 并给出了部分程序的源代码 关键词 :ADO.NET;ASP.NET;Web 数据库 ;BLOB 数据类型文献标识码 : A 1. 引言今天的应用程序和 Web 站点不但需要对文本和数字信息的存储和检索, 而且在 Web 数据库应用程序中还经常需要对图片 声音 视频及各种 Office 文档进行存储与利用, 这些非结构化的数据通常被称作二进制大对象 (BLOB) 在 Oracle 数据库中专门提供了一种 BLOB 数据类型, 可以很好地存储这些二进制数据 BLOB 数据类型是一种可用于存储大批量二进制数据的类型, 其最大长度可达 4G 字节 [1] ASP.NET 是建立在 Microsoft.NET 平台框架上的新技术, 利用公共语言运行时 (Common Language Runtime) 在服务器端为用户提供强大的企业级 Web 应用程序的编程架构 ASP.NET 继承了 ASP 的优点, 并且更加全面的引入面向对象的程序设计 (OOP) 思想, 使原来繁琐的程序设计在 ASP.NET 中可以轻而易举地实现 ASP.NET 中对数据库的操作主要是利用 ADO.NET 技术, 通过 VB.NET C# 等编程语言实现对数据的连接, 完成对数据的存取 查询 修改和删除等功能 本文以图片 声音等文件的存取与显示为例, 采用 C# 编程语言, 实现对 Oracle 数据库中 BLOB 类型数据的访问 2. 关于 ADO.NET 技术 2.1 ADO.NET 的数据模型 ASP.NET 使用 ADO.NET 数据模型 该模型从 ADO 发展而来, 但不只是对 ADO 的改进, 而是采用一种全新的技术 [2] 主要表现如下几个方面: ADO.NET 不是采用传统的 ActiveX 技术, 而是与微软新一代革命性的.NET 框架紧密结合的产物 ADO.NET 包含对 XML 标准的完全支持, 这对于跨平台交换数据和共享信息具有十分重大的意义 ADO.NET 既能在与数据源连接的环境下工作, 又能在与数据源连接断开的条件下工作 尤其后者, 非常适合于网络应用的需要 基于 ADO.NET 的数据模型系统也正是集中主要精力用于解决在断开与数据源连接的条件下数据处理的问题 2.2 ADO.NET 的技术特点 - 1 -
在.NET Framework 中,ADO.NET 是重要的应用程序级别的接口, 为创建分布式数据共享应用程序提供了丰富的组件 [3] 它提供了对关系数据 XML 和应用程序数据的访问, 是.NET Framework 中不可或缺的一部分 ADO.NET 体系结构中的两个核心组件是.NET 数据提供程序 (Provider) 和数据集 (DataSet) 其中.NET 数据提供程序, 是一组包括 Connection Command DataReader DataSet 及 DataAdapter 对象在内的组件, 其设计目的是为了访问数据和实现数据操作 Connection 对象提供与数据源的连接 Command 对象用于访问和返回数据 修改数据 运行存储过程以及发送或检索参数信息的数据库操作命令 DataReader 对象从数据源中提供高性能的数据流 DataAdapter 使用 Command 对象在数据源中执行 SQL 命令, 以便将数据加载到 DataSet 对象中, 并使对 DataSet 中数据的更改与数据源保持一致, 是连接 DataSet 对象和数据的桥梁 Dataset 是 ADO.NET 的断开式结构的核心组件, 它设计的目的是为了实现独立于任何数据源的数据访问, 数据集是表的本地缓冲区或断开连接的记录集的集合 因此, 它可以用于多种不同的数据源, 用于 XML 数据, 或用于管理应用程序本地的数据 3. 设计与实现 3.1 定义数据表结构 使用 Oracle 10g 作为后台数据库管理系统 首先建立 orcl 数据库, 然后在其中建立数据表 blob_table 用来存储二进制大对象数据文件, 其结构如表 1 所示 表 1 blob_table 表结构说明 字段名称 数据类型 字段大小 字段说明 file_id NUMBER 6 文件序号 file_name VARCHAR2 50 文件名称 file_type VARCHAR2 50 文件类型 file_content BLOB 文件内容 file_remark VARCHAR2 250 文件说明 在定义合理的数据表结构时, 首先应判断同名数据表是否存在, 如果存在就执行 Drop 命 令语句, 将原数据表删除, 然后创建新表, 其 SQL 脚本如下 : CREATE TABLE "PROJECT"."BLOB_TABLE" ( "FILE_ID" NUMBER(6), "FILE_NAME" VARCHAR2(50), "FILE_TYPE" VARCHAR2(50), "FILE_CONTENT" BLOB, "FILE_REMARK" VARCHAR2(250), CONSTRAINT "FILE_KEY" PRIMARY KEY ("FILE_ID") VALIDATE ) TABLESPACE "PROJECT" 3.2 建立数据库连接 在 Web 应用程序的 Web.config 配置文件中, 添加数据库连接字符串, 代码如下 : <connectionstrings> <add name="connstr" connectionstring = "server=orcl; uid=project;pwd=bysj"/> </connectionstrings> 在 Web.config 配置文件中设置的数据库连接字符串, 可以被 Web 应用程序的所有 aspx - 2 -
文件调用 调用时, 在相关文件的事件中定义数据库连接对象并设置其相关属性, 然后调用其打开数据库的连接函数, 从而建立起对数据库的连接 代码如下 : string connstr = ConfigurationManager. ConnectionStrings["ConnStr"].ConnectionString; conn = new OracleConnection(); conn.connectionstring = connstr; conn.open(); 3.3 存储内容到数据表 建立 UpLoadFile.aspx 窗体用于将文件内容转换成数据流存储到数据表中 首先把 Form 的 enctype 属性设置为 multipart/form-data; 其次在窗体添加 FileUpload 控件获取所选文件的相关信息 :PostedFile.FileName 获取文件路径字符串, 然后通过 Path.GetFileName() 方法获取文件名称 ;PostedFile.ContentType 获取文件的类型 ;PostedFile.ContentLength 获取文件的字节大小 ;PostedFile.InputStream 获取文件二进制数据流 最后点击上传按钮, 就可以将所选文件存入数据表中 上传按钮代码如下 : if (FileUpload1.PostedFile.FileName!= "") string filename; // 文件名称 string filetype; // 文件类型 int filesize; // 文件大小 Stream filecontent; // 文件内容 string fileremark; // 文件说明 // 获取文件名称 filename = Path.GetFileName(FileUpload1. PostedFile.FileName); // 获取文件类型 filetype = FileUpload1.PostedFile.ContentType; // 获取文件大小 filesize = FileUpload1.PostedFile.ContentLength; // 文件数据流 filecontent = FileUpload1.PostedFile.InputStream; byte[] storefilecontent = new byte[filesize]; int intstatus = filecontent.read(storefilecontent, 0, filesize); fileremark = tb_fileremark.text.trim(); string connstr = ConfigurationManager. ConnectionStrings["ConnStr"].ConnectionString; // 创建并实例化一个数据库连接对象 OracleConnection conn = new OracleConnection(); conn.connectionstring = connstr; // 打开数据库连接 - 3 -
conn.open(); string sqlstr = "INSERT INTO blob_table(file_id, file_name,file_type,file_content,file_remark) VALUES(seq_blob.nextval,&name, &type, &content,&remark)"; // 创建并实例化一个数据库命令对象 OracleCommand cmd = new OracleCommand(); cmd.commandtext = sqlstr; cmd.connection = conn; // 定义参数 cmd.parameters.add("&name", OracleType.VarChar, 50); cmd.parameters.add("&type", OracleType.VarChar, 50); cmd.parameters.add("&content", OracleType.Blob); cmd.parameters.add("&remark", OracleType.VarChar, 250); // 为参数赋值 cmd.parameters["&name"].value = filename; // 文件名称 cmd.parameters["&type"].value = filetype; // 文件类型 cmd.parameters["&content"].value = storefilecontent; // 文件内容 cmd.parameters["&remark"].value = fileremark; // 文件说明 try cmd.executenonquery(); catch (Exception ex) Response.Write(" 数据库错误, 错误原因 :" + ex.message); Response.End(); finally if (cmd.connection.state == ConnectionState. Open) cmd.connection.close(); cmd.connection.dispose(); cmd.parameters.clear(); cmd.dispose(); - 4 -
3.4 读取数据表内容 建立 ViewInfo.aspx 页面用于读取数据表中 file_id,file_name,file_type 和 file_remark 字段内容 首先在 Form 窗体上添加一个 GridView 控件, 设置其 DataKeyNames 属性为 file_id, 并将其 AutoGenerateColumns 行为设置为 false 然后编辑 GridView 控件的列, 将数据表中需要显示的字段进行绑定 [4], 并另外添加一个 HyperLinkField 字段, 设置其属性 DataNavigateUrlFields 为 file_id 和 DataNavigateUrlFormatString 为 ShowContent. aspx?id=0, 用于显示或下载数据表中存储的大对象数据 页面加载后, 当用户点击 HyperLinkField 字段内容时,ViewInfo.aspx 页面将 file_id 字段作为查询参数传递给 ShowContent.aspx 页面 在 ShowContent.aspx 的 Page_Load 事件中先得到 ViewInfo.aspx 页面传递过来的 file_id 值, 再按照数据的原来类型将文件信息显示在客户端浏览器上或是下载下来利用 Page_Load 事件中的程序代码如下 : // 获取 ViewInfo.aspx 页面传递过来的参数 int id = Int32.Parse(Request.QueryString["id"]. ToString()); // 获取数据库连接字符串 string connstr = ConfigurationManager. ConnectionStrings["ConnStr"].ConnectionString; OracleConnection conn = new OracleConnection (connstr); OracleCommand cmd = new OracleCommand(); string sqlstr = "SELECT file_type,file_content FROM blob_table WHERE file_id=" + id; cmd.commandtext = sqlstr; cmd.connection = conn; try conn.open(); OracleDataReader odr = cmd.executereader( CommandBehavior.SequentialAccess); while (odr.read()) OracleLob olb = odr.getoraclelob(1); int olblen = Convert.ToInt32(olb.Length); byte[] buffer = new byte[olblen]; olb.read(buffer, 0, olblen); Response.Clear(); // 数据编码方式 Response.ContentEncoding = System.Text. Encoding.Default; // 设置输出流的 HTTP MIME 类型 Response.ContentType = odr["file_type"]. - 5 -
ToString(); // 将一个二进制字符串写入 HTTP 输出流 Response.BinaryWrite(buffer); Response.End(); odr.close(); catch (Exception ex) Response.Write(" 数据库错误, 错误原因 :" + ex.message); Response.End(); finally if (conn.state == ConnectionState.Open) conn.close(); 本代码中使用了 BinaryWrite 函数, 将一个二进制字符串写入 HTTP 输出流并在 Web 页面上进行显示或是下载 该函数可以用于在浏览器中显示图像 声音 视频及各种 Office 文档数据 4 结论 本文通过对 ADO.NET 技术的分析研究, 提出了使用 Oracle 10g 数据库中 BLOB 数据类型来存取大对象数据的实现方法 通过 ADO.NET 技术实现了对 Oracle 数据库的访问, 采用 C# 编程语言实现了 Web 应用程序对数据的存取 参考文献 [1] Jason Price 著. 冯锐, 由渊霞译. Oracle Database 10g SQL 开发指南 [M]. 北京 : 清华大学出版社,2005. [2] 程不功, 龙跃进. ASP.NET 2.0 动态网站开发教程 [M]. 北京 : 清华大学出版社,2006. [3] 陈语林. ASP.NET 2.0 程序设计 [M]. 北京 : 中国水利水电出版社,2008. [4] BUCZEK G. 程永敬, 韩平译. ASP.NET 技术与技巧 [M]. 北京 : 机械工业出版社,2003. Study on Accessing BLOB Data by using ASP.NET Technology Fang Zifan, Chen Shaoping, Wu Jianhua, Shu Wenhui Mechanical & Material College in China Three Gorges University, Yichang Hubei (443002) Abstract: Through analyzing and studying data model and summarizing characterizes of ADO.NET Technology, the methods of accessing BLOB data in database are put forward. And with parts of source code followed, it is explained how to store and display image, audio, video and office archives etc on browser in web database application system using ASP.NET and Oracle 10g through examples. In addition, the examples is realized by utilizing C#, it is put forward an effective method for BLOB data accessing including lots of files in database. Keywords: ASP.NET; ADO.NET; Web database; BLOB data - 6 -