SQL Server总结(2):对数据库访问

在上一篇文章中讲到了程序与数据库的连接,下面总结一下程序对数据库中数据的访问。

对数据的访问分两种方式:

方式一:采用Command、DataReader对象,优点是读取数据的速度比较快,但需要编写的代码比较长。

方式二:采用DataAdapter、Dataset、DataGrid对象,需要编写的代码短,但需要占用额外的内存,并且读写速度比方式一慢。

下面介绍方式一的几个重要对象:

SplConnection对象

1、connection的理解

Connection对象表示与特定数据源的连接

不同的数据源,对应不同的Connection对象

名称        命名空间              描述
SqlConnection System.Data.SqlClient 表示与SQL Server的连接对象  
OleDbConnection System.Data.OleDb 表示与OleDb数据源的连接对象    

OdbcConnectionSystem.Data.Odbc 表示与ODBC数据源的连接对象           

OracleConnectionSystem.Data.OracleClient 表示与Orale数据库的连接对象

DbConnection是抽象的基类,并且继承Compoent、IDbConnection、IDisposable

建立一个数据库连接是一件非常耗时(消耗时间)耗力(消耗资源)的事情。之所以会这样,是因为连接到数据库服务器需要经历几个漫长的过程:建立物理通道(例如套接字或命名管道),与服务器进行初次握手,分析连接字符串信息,由服务器对连接进行身份验证,运行检查以便在当前事务中登记等等。我们先不管为什么会有这样的机制,存在总是有它的道理。既然新建一条连接如此痛苦,那么为什么不重复利用已有的连接呢?

2、连接池

ADO.NET已经为我们提供了名为连接池的优化方法。连接池就是这样一个容器:它存放了一定数量的与数据库服务器的物理连接。因此,当我们需要连接数据库服务器的时候,只需去池(容器)中取出一条空闲的连接,而不是新建一条连接。这样的话,我们就可以大大减少连接数据库的开销,从而提高了应用程序的性能。

连接池的行为可以通过连接字符串来控制,主要包括四个重要的属性:
Connection Timeout:连接请求等待超时时间。默认为15秒,单位为秒。
Max Pool Size: 连接池中最大连接数。默认为100。
Min Pool Size: 连接池中最小连接数。默认为0。
Pooling: 是否启用连接池。ADO.NET默认是启用连接池的,因此,你需要手动设置Pooling=false来禁用连接池。

3、分配空闲连接

当用户创建连接请求或者说调用Connection对象的Open时,连接池管理器首先需要根据连接请求的类型签名找到匹配类型的连接池,然后尽力分配一条空闲连接。具体情况如下:

如果池中有空闲连接可用,返回该连接。

如果池中连接都已用完,创建一个新连接添加到池中。

如果池中连接已达到最大连接数,请求进入等待队列直到有空闲连接可用。

4、移除无效连接

无效连接,即不能正确连接到数据库服务器的连接。对于连接池来说,存储的与数据库服务器的连接的数量是有限的。因此,对于无效连接,如果如不及时移除,将会浪费连接池的空间。其实你不用担心,连接池管理器已经很好的为我们处理了这些问题。如果连接长时间空闲,或检测到与服务器的连接已断开,连接池管理器会将该连接从池中移除。

5、回收连接

使用完一条连接时,应当及时关闭或释放连接,以便连接可以返回池中重复利用。可以通过Connection对象的Close或Dispose方法,也可以通过C#的using语句来关闭连接。

当用户打开一个连接而没有正确或者及时的关闭时,经常会引发“连接泄露”问题。泄露的连接,会一直保持打开状态,直到调用Dispose方法,垃圾回收器(GC)才关闭和释放连接。与ADO不同,ADO.NET需要手动的关闭使用完的连接。一个重要的误区是:当连接对象超出局部作用域范围时,就会关闭连接。实际上,当超出作用域时,释放的只是连接对象而非连接资源。

例一:conn.Close()//关闭连接   

     conn.Dispose()//释放资源

例二:using (SqlConnection conn2 = new SqlConnection(@"DataSource=(LocalDB)\v11.0;

               AttachDbFilename=F:\c#\Database1.mdf;Integrated Security=True"))

使用using,using语句的作用是确保资源使用后,并很快释放它们。using语句帮助减少意外的运行时错误带来的潜在问题,它整洁地包装了资源的使用。具体来说,它执行以下内容:
a、分配资源。
b、把Statement放进try块。
c、创建资源的Dispose方法,并把它放进finally块。

例三:

try
{
conn.Open();
}
catch(Exception ex)
{
;//todo

}
finially
{
conn.Close();
}

 必须掌握的几个方法
Open: 使用 ConnectionString 所指定的设置打开数据库连接。
Dispose: 释放由 Component 使用的所有资源。
Close: 关闭与数据库的连接。 此方法是关闭任何已打开连接的首选方法。Close 方法回滚任何挂起的事务。 然后,它将连接释放到连接池,或者在连接池被禁用的情况下关闭连接。

 必须掌握的几个属性
Database: 在连接打开之后获取当前数据库的名称,或者在连接打开之前获取连接字符串中指定的数据库名。
DataSource: 获取要连接的数据库服务器的名称。
ConnectionTimeOut: 获取在建立连接时终止尝试并生成错误之前所等待的时间。
ConnectionString: 获取或设置用于打开连接的字符串。
State: 获取描述连接状态的字符串。
ConnectionState:描述了与数据源的连接的当前状态

ConnectionState是一个枚举类型。它包括以下成员:
Closed: 连接处于关闭状态。
Open: 连接处于打开状态。
Connecting: 连接对象正在与数据源连接。
Executing: 连接对象正在执行命令。
Fetching: 连接对象正在检索数据。
Broken: 与数据源的连接中断。
SplComand对象

封装了所有对外部数据源的操作(包括增、删、查、改等SQL语句与存储过程),并在执行完成后返回合适的结果。与Connection对象一样,对于不同的数据源,ADO.NET提供了不同的Command对象。

必须掌握的几个属性
 CommandText: 获取或设置对数据源执行的文本命令。默认值为空字符串。
 CommandType: 命令类型,指示或指定如何解释CommandText属性。CommandType属性的值是一个枚举类型,定义结构如下:
public enum CommandType    
{      Text = 1,    //SQL 文本命令。(默认。)          
        StoredProcedure = 4,    // 存储过程的名称。          
        TableDirect = 512    //表的名称。  
}
需要特别注意的是,将CommandType 设置为 StoredProcedure 时,应将 CommandText 属性设置为存储过程的名称。 当调用 Execute 方法之一时,该命令将执行此存储过程。
Connection: 设置或获取与数据源的连接。
Parameters: 绑定SQL语句或存储过程的参数。参数化查询中不可或缺的对象,非常重要。
Tranction: 获取或设置在其中执行 .NET Framework 数据提供程序的 Command 对象的事务。
必须掌握的几个方法
 ExecuteNonQuery: 执行不返回数据行的操作,并返回一个int类型的数据。
 注意:对于 UPDATE、INSERT 和 DELETE 语句,返回值为该命令所影响的行数。 对于其他所有类型的语句,返回值 为 -1。
 ExecuteReader: 执行查询,并返回一个 DataReader 对象。
 ExecuteScalar: 执行查询,并返回查询结果集中第一行的第一列(object类型)。如果找不到结果集中第一行的第一列,则返回 null 引用。

常用SQL语句:

用户对数据源的操作不外乎CRUD-S(Create、Update、Delete、Select)操作。

一般地,在执行非查询操作时,我们需要调用ExcuteNonQuery方法

///删除表中全部数据

string SQLStr = "delete table1 where(1=1)";

///删除表中指定日期范围的数据

///获取表中指定日期范围的数据

string datetimetemp1 = "'" + "2016-3-1016:08:59" + "'";//格式很重要

string datetimetemp2 = "'" + "2016-3-1018:08:00" + "'";

string SQLStr = "delete from table1 where convert(datetime,Time)>" + datetimetemp1 +

"and convert(datetime,Time)<" + datetimetemp2;

///读取指定时间段内数据

string SQLStr = "select * from table1 whereconvert(datetime,Time)>" + datetimetemp1 +

"and convert(datetime,Time)<" + datetimetemp2 + "order byTime";

///读取全部数据

 

string SQLStr = "select * from table1";

///获取表中数据行数

string SQLStr="select count(*) from table1";

/*插入数据*/

//insert into table1(Time,TempSensor1) values (‘2016-3-8 21:06:06’,73.58);

string SQLStr = "insert table1(Time ,TempSensor1)values(@Time,@TempSensor1)";

/*创建表*/

// string SQLStr "create table table1(Time nvarchar(20),TempSensor1float)";

/*删除表*/

// string SQLStr ="drop table table1";


你可能感兴趣的:(SQL Server总结(2):对数据库访问)