ADO.NET 基础(Connection、Command、DataReader)
2012-07-16 15:04
239 查看
ADO.NET架构
ADO.NET数据提供程序数据提供程序是一组用于访问特定数据库,执行SQL命令并获取值的ADO.NE类,就其本质而言,数据提供程序是应用程序和数据元之间的一座桥梁。
数据提供程序包括以下几个类:
Connection:建立和数据源的连接
Command:执行SQL命令和存储过程
DataReader:提供对查询结果的快速只读,只进的访问方式,它是保持连接的处理方式
DataAdapter:从数据源获得信息填充到DataSet,依照DataSet的修改更新数据源,它是一系列表和关系的集合,它是断开连接的处理方式
ADO.NET没有提供通用的数据提供程序,它只为不同数据源和特别设计不同数据提供程序。每个数据提供程序包含为特定RDBMS(关系型数据库管理系统)特别实现的Connection、Command、DataReader类。
.NETFramework提供4个提供程序:
SQLServer:提供对SQLServer数据库的优化访问
OLEDB:提供对有OLEDB驱动的任意数据源的访问
Oracle:提供对Oracle数据库访问
ODBC:提供对有ODBC驱动的任意数据源访问
自.NET4开始,Oracle提供程序被废弃,虽然仍可以使用它,但微软推荐使用第三方ADO.NET提供程序访问Oracle数据库,比如Oracle发布的ODP.NET,它为特殊的Oracle数据类型【如LOB(大对象)、时间戳、XML数据】提供更丰富的支持,此外还有一些特性。
ADO.NET的标准化
初看起来,ADO.NET似乎提供了一个松散的模型,它没有提供能够和不同类型的数据库一起工作的通用对象,这样,如果换了RDBMS,就需要修改数据访问代码以实用不同的类。(不同数据提供程序使用完全不同的底层方法和API,各有各的特色和优化,因此也无法通用)。这个模型的好处和效果也许不是那么明显,但确实有好处:
每个提供程序使用相同的接口和基类,所以基于接口而不是基于提供程序类的编码仍可以写出通用的数据访问代码。(但要付出一些额外的代价)
每个提供程序分别独立实现,拥有各自的优化
自定义提供程序还可以加入其他提供程序没有的非标准特性(如SQLServer执行XML查询的能力)
基本ADO.NET类
ADO.NET有两种类型的对象:
基于连接的对象:如Connection、Command、DataReader和DataAdapter,它们连接到数据库,执行SQL语句,基于连接的对象是针对具体数据源类型的,并且可以在各自的命名空间中(例如SQLServer提供程序的System.Data.SqlClient)找到。
基于内容的对象:包括DataSet、DataColumn、DataRow、DataRelation等,它们完全和数据源独立,出现在System.Data命名空间里。
ADO.NET支持的最重要命名空间:
System.Data | 关键数据容器类。包括列、关系、表、数据集、行、视图和约束建立模型。 |
System.Data.Common | 包括大部分基本的抽象类,这些类实现System.Data中的某些接口并定义了ADO.NET的核心功能。 数据提供程序继承这些类来创建它们自己的版本。 |
System.Data.OleDb | 包含用于连接OLEDB提供程序的类。这些类支持大部分OLEDB提供程序。 |
System.Data.SqlClient | 包含用于连接微软SQLServer数据库所需的类,这些类经过优化以便使用SQLServer的TDS接口。 |
System.Data.OracleClient | 包含用于连接Oracle数据库的类,这些类使用经过优化的Oracle调用接口(OCI) |
System.Data.Odbc | 包含连接大部分ODBC驱动所需的类。 所有数据源都包含ODBC驱动,并可以通过“控制面板”中的“数据源”快捷方式配置。 |
System.Data.SqlTypes | 包含SQLServer本地数据类型相对应的类型。 这些类不是必须的,但它们提供了一种使用标准.NET数据类型的选择,这是自动类型转换时所必需的。 |
Connection类
Connection类用于和要交互的数据源建立连接,在执行任何操作前(增、删、改、查)必须建立连接。连接字符串
创建Connection对象时,必须先提供连接字符串。连接字符串是以分号(;)分隔的一系列名称/值对的选项,这些选项的顺序并不重要,大小写也不重要。
尽管随着RDBMS和提供程序的不同,连接字符串也不同,但基本需要的信息如下:
数据库所在的服务器
要使用的数据库名称
如何通过数据库验证
比如下面这个连接字符串使用整合安全(用当前登录windows用户身份访问数据库)方式连接本机的Northwind数据库:
stringconnStr="DataSource=localhost;InitialCatalog=Northwind;IntegratedSecutiry=SSPI"//SSPI等同于True
如果数据库不支持整合安全,就必须指定有效的用户名和密码,例如:
stringconnStr="DataSource=localhost;InitialCatalog=Northwind;userid=sa;password=xxx"
若使用OLEDB提供程序,连接字符串和前面的相似,但需要额外添加一个提供程序设置来标识OLEDB驱动
stringconnStr="DataSource=localhost;InitialCatalog=Northwind;userid=sa;password=xxx;Provider=MSDAORA"
通过MSDAORAOLEDB提供程序访问Oracle数据库
连接Access数据库
stringconnStr="Provider=Microsoft.Jet.OLEDB.4.0;DataSource=C:\DataSources\Northwind.mdb"
没有任何理由硬编码数据库连接字符串,web.config文件的<connectionStrings>节便于保存和随时修改连接字符串:
<connectionStrings>
<addname="Northwind"connectionString="DataSource=localhost;InitialCatalog=Northwind;IntegratedSecutiry=SSPI"/>
</connectionStrings>
接着可以使用名称从WebConfigurationManager.ConnectionStrings集合中读取连接字符串(导入System.Web.Configuration命名空间):
stringconnStr=WebConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
测试连接
protectedvoidPage_Load(objectsender,EventArgse)
{
stringconnStr=WebConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
SqlConnectionconn=newSqlConnection(connStr);
try
{
conn.Open();
lblInfo.Text="<b>ServerVersion:</b>"+conn.ServerVersion;
lblInfo.Text+="<br/><b>ConnectionState:</b>"+conn.State.ToString();
}
catch(Exceptionerr)
{
lblInfo.Text="Errorreadingthedatabase."+err.Message;
}
finally{
conn.Close();
lblInfo.Text+="<br/><b>ConnectionState:</b>"+conn.State.ToString();
}
}
连接时有限的服务器资源,要尽量晚打开而尽早释放。finally块确保了连接能够被关闭,否则如果发生了异常,连接将一直保持到垃圾回收器释放SqlConnection对象。
另一种方法是把数据访问代码放入到using块中。using语句用来声明正在短期使用的一个可释放的对象,最妙的是你不编写finally块,即使由于未处理的异常而退出该块,using语句也会释放正在使用的对象。
stringconnStr=WebConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
SqlConnectionconn=newSqlConnection(connStr);
using(conn)
{
conn.Open();
lblInfo.Text="<b>ServerVersion:</b>"+conn.ServerVersion;
lblInfo.Text+="<br/><b>ConnectionState:</b>"+conn.State.ToString();
}
lblInfo.Text+="<br/><b>ConnectionState:</b>"+conn.State.ToString();
连接池
虽然请求连接耗时很短,但它们确实需要时间。在Web应用程序中,随着请求的处理连接被不断的打开和关闭,每个请求都被高效处理。在这样的环境中,即使建立连接所需要的微小消耗也会显著影响系统性能。
一个解决办法是使用连接池。连接池保证已经打开的数据库连接,这些连接在使用相同数据源的会话间共享,这样就省了不断创建和销毁连接的时间。当客户用Open()方法请求打开连接时,连接直接由连接池提供而不是再次创建。当客户调用Close()方法或Dispose()方法释放连接时,它并没有被真的释放而是重新回到池中等待下一次请求。
ADO.NET并不包含任何连接池的机制,但是大部分数据库提供程序提供对连接池的实现。
为了使用SQLServer或Oracle的连接池,连接字符串必须完全匹配。即使只有微小的差异(哪怕只是修改了参数的顺序或是多了一个空格),也会在新池中创建新连接,这也是不要硬编码连接字符串的原因。
SQLServer和Oracle提供程序都是自动使用连接池的。
MaxPoolSize | 池中允许最大连接数(默认100),如已达最大数,所有打开连接请求将排队等候 |
minPoolSize | 池中最小连接数(默认0),第一次打开时会建立相应数量的连接,所以第一次请求时会稍微有点延迟 |
Pooling | 为true(默认值)时,连接从池中获取 |
ConnectionLifetime | 指定以秒为单位的时间间隔,默认是0。池中的连接创建时间早于指定生命周期,将被销毁。 当需要大量回收连接时,该功能很有效 |
stringconnStr="DataSource=localhost;InitialCatalog=Northwind;IntegratedSecurity=SSPI;MinPoolSize=10"