您的位置:首页 > 数据库

C#二十五 连接式访问数据库

2016-05-07 18:58 309 查看
在连接式访问数据库方式下,数据库就好比一个水池,你要取水池里的水进行操作就必须先建立一条管道,连接就相当于通向数据库的管道。在操作时连接不可以断开,一旦连接断开将造成数据访问的严重错误。

我们知道真正的水池能建立的管道必定有限,对于数据库也是一样的,同一个数据库能在同一时间接受的连接是有限的。缺点是并发性差,比如针对多并发操作的程序,有点是可以快速高效的操作数据库。

重点:

Ø SqlConnection对象

Ø SqlCommand对象的增、删、改、查操作

Ø SqlDataReader对象从数据库读取数据

Ø 资源释放

预习功课:

Ø SqlConnectioni对象的声明与使用

Ø SqlCommand对象常用方法

Ø SqlDataReader对象如何读取数据

Ø 为何要进行数据连接的资源释放

2.1 进水笼头——建立Connection
Connection表示与数据源之间的连接。可根据Connection对象的各种不同属性来指定数据源的类型、位置及其他属性,可用它来与数据库建立连接或断开连接。其他对象如DataAdapter和Command对象通过它与数据库通信。根据.NET Framework 数据提供程序的不同,也有几种不同的Connection,如针对SQL Server的SqlConnection、针对Oracle的OracleConnection、针对MySQL的MySqlConnection、针对OLEDB的OleDbConnection等。(本节代码示例位置:光盘\code\ch05\01)
1.用SqlConnection连接SQL Server
(1)加入命名空间:
1. using System.Data.SqlClient;
(2)连接数据库:
1. string conString = "data source=127.0.0.1;Database=codematic;user id=sa;

password=";
2. SqlConnection myConnection = new SqlConnection(conString);
3. myConnection.Open();
2.用OracleConnection连接Oracle
首先添加OracleClient的引用,如图5-5所示。



(1)加入命名空间:
1. using System.Data.OracleClient;
(2)连接数据库:
1. string conString = "Data Source=codematic;User ID=codeuser;

Password=user123";
2. OracleConnection myConnection = new OracleConnection(conString);
3. myConnection.Open();

3.用MySqlConnection连接MySQL
在.NET中连接MySQL数据库有两种方法:MySQL Connector/ODBC 和 MySQL Connector/NET,ODBC连接器是符合ODBC标准的交互平台,是.NET访问MySQL数据库的最好的选择。
首先,我们下载安装MySql-connector-net-5.1.5.Data.msi这个组件。如果是默认安装,则可以在C:\Program Files\MySQL\MySQL Connector Net 5.1.5\Binaries\.NET 2.0(这里安装的是MySQL Connector/Net 5.1.5,老的1.1版本是:C:\Program Files\MySQL\MySQL Connector
Net 1.0.4\bin\.NET 1.1\)中找到MySql.Data.dll,将该文件复制到项目的bin目录下。
然后在项目引用中添加MySql.Data.dll的引用,如图5-6所示。



实现代码如下。
(1)加入命名空间:
1. using MySql.Data.MySqlClient;
(2)连接数据库:
1. string conString = "server=127.0.0.1;database=mysql;user id=root;

password=123";
2. MySqlConnection myConnection = new MySqlConnection(conString);
3. myConnection.Open();
4.用OleDbConnection连接各种数据源
由于数据源不同,相应的连接字符串也会不同。
(1)加入命名空间:
1. using System.Data.OleDb;
(2)连接SQL Server:
1. string conString = " Provider=SQLOLEDB.1;Persist Security Info=False;
2. User ID=sa;Database=Codematic;Data Source=COMPUTER";
3. OleDbConnection myConnection = new OleDbConnection(conString);
4. myConnection.Open();
(3)连接Access(可通过建立.udl文件来获得字符串):
1. string conString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source
2. =C:\\Database1.mdb;Persist Security Info=False";
(4)连接Oracle(也可通过OracleConnection连接):
1. string conString = "Provider=MSDAORA.1;User ID=user; Password=123;
2. Data Source=db;Persist Security Info=False";
从以上几个对象实例对比来看,几个.NET数据提供程序组件模型的基本编程模式相同,只是组件对象的前缀有所区别,正是这种统一编程模型,让我们在做不同类型数据库开发时,变得非常简单。

下面我们主要来研究SqlConnection连接类的重要属性和方法:

属性
说明
ConnectionString

连接字符串

DataBase

获取连接打开的数据库名称

State

获取连接对象的状态

方法
说明
Open

打开数据库连接

Close

关闭数据库连接

要建立一个数据库的连接,必须给数据库对象足够的关于它要连接的数据库的信息,这些信息包括数据库服务器名称、数据库名称、数据库账户、账户密码等。由这些链接信息组成的连接字符串叫“数据库连接字符串”。格式如下:

string conn="server=.;database=NIIT;uid=sa;pwd=123456";

下面来解释下数据库连接字符串:

n server:后面跟数据库服务器的名称;可以为本机地址(.、local、或127.0.0.1);或对方数据库服务器名称或IP,如:"ha001.mobile"、"224.68.102.86"。

n database:你要访问的服务器的名称,也可写成"Initial Catalog";

n uid:登录数据库账户的名称,也可写成"user id";

n pwd:登录数据库账户的密码,密码为空时,pwd不能省略,可以这样写"uid=sa;pwd=";

有了数据库连接字符串,就可以直接建立数据库连接对象了:

SqlConnection cn=newSqlConnection(server=.;database=NIIT;uid=sa;pwd=123456");

建立了数据库连接后,如果要通过该连接操作数据库里面的数据,还需要打开该连接:

cn.Open();

如果该数据库连接使用完了,可以调用Close()方法关闭该连接,如:

cn.Close();

要注意每个数据库能接受的连接是有限的,每个连接都可以为一个应用程序服务,所以,数据连接式非常宝贵的资源。因此,在操作数据库连接对象时要注意谨慎,要使用异常结构确保连接使用完后正常释放。

为什么使用异常处理,可能会有如下情况:

n 与数据库的连接中断

n 无法打开数据库

n 无法操作数据

n …

一个完整并且有效的使用数据库连接对象的例子如下:

using System;

using System.Data.SqlClient;

class DataDemo

{

static void Main(string[]args)

{

//通过连接字符串建立数据库连接

SqlConnection cn=newSqlConnection("server=.;database=School;uid=sa;pwd=123456;");

try

{

//打开数据库连接

cn.Open();

Console.WriteLine("连接建立成功!");

}catch(SqlException ex)

{

//要对连接异常做仔细的处理

Console.WriteLine(“连接数据库出错:"+ex.Message);

}

finally

{

//一定要确保数据连接正常释放

cn.Close();

}

}

}

运行结果如果显示"连接建立成功",那么表示你建立的数据库连接是有效的。数据连接一旦建立,我们就可以通过连接对象的State属性获得此连接的状态,连接状态用一个ConnectionState枚举表示,常用的连接状态只有两种:

l Open:表示连接处于打开状态

l Close:表示连接处于关闭状态

我们可以通过判断连接状态来合理的打开或关闭数据库连接,如:

if(cn.State==ConnectionState.Open)

cn.Close();

if(cn.State==ConnectionState.Closed)

cn.Open();

要注意ConnectionState枚举属于System.Data命名空间,在使用这个枚举时别忘了导入这个命名空间。

Sql Server数据库有两种登录方式,一种是SqlServer账户登录方式,一种是Windows集成登录方式。前面我们已经使用过Sql Server账户登录方式了,还可以通过Windows集成验证方式登录,这种登录会把Windows集成验证的安全证书传给数据库服务器,所以不需要密码,要使用Windows登录验证只需修改数据库连接字符串为如下即可:

SqlConnection cn=new SqlConnection("server=.;database=School;uid=sa;pwd=123456;IntergratedSecurity=SSPI");

如前所述,数据库一旦建立,也就是开通了一条存取数据库连接的通道。以数据库连接为基础再结合数据库的操作对象(如下面将介绍的命令对象)就可以存取数据库里的数据了。

2.2 对数据库进行增、删、改、查操作

抽水机:Command

通过Ado.Net中的Command命令对象可以向数据库服务器发送一个操作命令。这些操作命令包括执行某个SQL语句或调用某个存储过程。有了命令对象我们就可以对数据库进行增、删、改、查等操作了。Command命令对象时建立在数据库连接基础上的,所以在调用命令对象操作数据库时要保证数据库连接已经打开。

Ado.Net为我们提供SqlCommand类也在System.Data.SqlClient命名空间下:

属性
说明
Connection

Command对象使用的数据库连接

CommandText

执行的SQL语句

CommandType

命令对象的类型,主要包括两种类型,一表示要执行Sql语句,

一种表示要调用存储过程

Parameters

与命令对象关联的参数集合对象

Transaction

与命令对象关联的事物对象

方法
说明
ExecuteNonQuery

执行不返回行的语句,如UPDATE等

ExecuteReader

返回DataReader对象

ExecuteScalar

返回单个值,如执行COUNT(*)

2.2.1使用Command步骤:

1、创建数据库连接

2、定义 SQL 语句

3、创建 Command 对象(执行命令前,必须打开数据库连接!)

4、执行命令

SqlCommand类为我们提供了两个常用的方法可以执行查询操作,一个方法是ExecuteScalar()方法,它返回一个值;另外一个是ExecuteReader()方法,它返回一个SqlDataReader()类型的结果集。

要使用ExecuteScalar()方法在构造Sql语句时一般要带聚合函数如:

Select Count(*) From Admin //计算有多少人

Select Average(age) From UserInfo //计算平均年龄

ExecuteScalar()方法一般用在某些特殊的情况下,比如用户验证(判断这个用户是否在该数据库中),再比如求平均值。其返回类型为Object类型的,所以,需要对结果进行强制转换才能得到你想到的值。

部分代码:

SqlConnection connection = newSqlConnection(connString);

string sql = "SELECT COUNT(*) FROMStudent";

connection.Open();// 打开数据库连接

SqlCommand command = newSqlCommand(sql, connection);

int num = (int)command.ExecuteScalar();

综合示例

完成系统登录功能

1、验证管理员的用户名和密码是否存在

2、验证通过,显示管理员主窗体

分析:

ü 处理登录按钮的 Click 事件

ü 定义一个 ValidateUser() 方法

ü 需要 Connection 和 Command 对象

ü 分两步实现验证:

1、建立数据库连接

2、验证用户是否存在

ValidateUser() 方法框架:



ValidateUser() 方法具体实现

第一步:建立数据库连接

-增加 DBHelper 类

第二步:查询用户是否存在

-SELECT COUNT(*)

-ExecuteScalar() 方法查询

// 查询 Student 表使用的 SQL 语句

string sql = string.Format(

"SELECT COUNT(*) FROM Student WHERE LogInId='{0}'

AND LogInPwd='{1}'",txtLogInId, txtLogInPwd);

// 使用的 Command 对象

SqlCommand command = newSqlCommand(sql, DBHelper.connection);

DBHelper.connection.Open();

// 执行查询,返回找到的个数

count = (int)command.ExecuteScalar();

小结:

l Connection 对象的什么方法用来打开和关闭数据库连接?

l ExecuteScalar()方法返回什么?

2.2.2如何对数据库的数据进行增删改?

对于四大操作来说,增、删、改三大操作都是单向的,之所以叫单向操作就是因为这些操作只是修改数据库而不返回数据。只有查是双向操作,因为既需要数据库提交查询命令又需要操作从数据库返回的结果集。所有单向操作使用SqlCommand类的ExecuteNonQuery()方法来执行。

以教务信息系统增加学员为例:



处理“保存”按钮的 Click事件,使用ExecuteNonQuery() 方法向数据库增加记录

部分参考代码:

stringconnStr = "…";

SqlConnection connection = newSqlConnection(connStr);

// 插入记录用的 SQL 语句

string sql = string.Format(

"INSERTINTO Grade (GradeName) VALUES ('{0}')",

txtGradeName.Text);

// 创建 Command 对象

try

{

SqlCommand command= new SqlCommand(sql, connection);

// 打开数据库连接

connection.Open();

// 执行插入命令

int result =command.ExecuteNonQuery();

}catch(SqlException sqle)

{

Console.WriteLine("连接数据库出错"+sqle.Message);

}

finally

{

cn.Close();// 关闭数据库连接

}

//如果是删除数据,则将sql语句改写为Delete语句即可,例如从人员表中删除某条记录

string sql="Delete from Personwhere Id=’ha002.mobile’";

//如果是更新数据,则将sql语句改写为Update语句即可

string strSql2 = "update P_Product set Name='数码4' where Id=53";

2.3 如何从数据库读取数据:输水管--DataReader

通过调用SqlCommand对象的ExecuteReader()可以得到一个SqlDataReader结果集对象。SqlDataReader是一个只进式的记录读取器,它可以一条一条读取检索到的数据。如果数据库是水池,连接对象是管道,那么SqlDataReader就是水龙头,打开水龙头就会不断的流出。

因为SqlDataReader每次只能读取一条记录,所以你需要借助一个循环来读取所有的记录。你可以通过SqlDataReader的Read方法来读取下一条记录。同时Read方法还会返回一个bool型的值,借助这个值就可以判断是否已经读完,如果Read返回true,表示没有读完,否则表示读完。

通过SqlDataReader获取当前记录后,有四种方式获取该记录的列值。

2.3.1案例:使用 DataReader 查询数据



分析:

1. 需要自动添加“年级”组合框中的年级名称;

2. 处理窗体 Load 事件

3. 使用 DataReader 读取年级名称

关键代码:

// 执行查询省略…

SqlDataReader dataReader =command.ExecuteReader();

string gradeName =""; // 年级名称

// 循环读出所有的年级名,并添加到年级列表框中

while (dataReader.Read())

{ /*循环读取数据行添加到组合框中*/

gradeName = (string)dataReader[0];

cboGrade.Items.Add(gradeName);

}

dataReader.Close();

2.3.2 DataReader 的主要成员

属性
说明
HasRows

是否返回了结果

方法
说明
Read

前进到下一行记录

Close

关闭 DataReader 对象

DataReader 使用步骤小结

1、创建 Command 对象

2、调用 ExecuteReader() 创建DataReader 对象

3、使用 DataReader 的Read() 方法逐行读取数据

4、读取某列的数据,(type)dataReader[ i]

5、关闭 DataReader 对象

//注意:DataReader使用后必须关闭

//第4步获取某列值的方法有如下四种方式:

ü 第一种:通过列号

(type)dataReader[i]; //i:表示该列的列号,取值为0…n

ü 第二种:通过列名

(type)dataReader["列名"]

ü 第三种:通过GetValue()和列号

(type)dataReader.GetValue(i); //i: 表示该列的列号,取值为0…n

ü 通过GetX方法和列号

dataReader.GetString(i),dataReader.GetInt32(i)等;

这四种读取方式的主要区别在于效率的问题,前三种返回的都是object类型的数据,你需要进行拆箱操作(强制类型转换)才能使用该列的值。只有第四种返回的是具体数据类型的值,效率会高些。第四种方式应该根据数据库列的具体类型调用不同的Get方法,比如数据库类型是DateTime,则需要调用GetDateTime(i)方法。另外,第二种方法也比较常用。

2.3.3得到DataReader的列信息

dataReader.FieldCount 获取当前行中的列数
dataReader.GetFieldType(序号) 获取是对象的数据类型的 Type
dataReader.GetDataTypeName(序号) 获取源数据类型的名称
dataReader.GetName(序号) 获取指定列的名称
dataReader.GetOrdinal(序号) 在给定列名称的情况下获取列序号

2.3.4得到数据表的信息

DataTable dt=dr.GetSchemaTable();
2.3.5使用DataReader获得最佳性能的技巧
在使用带参数的Command前,必须关闭DataReader。
完成读数据之后一定要关闭DataReader。如果使用Connection只返回DataReader,那么关闭DataReader之后立刻关闭它。另外一个显式关闭Connection的方法是将CommandBehavior.CloseConnection传递给ExecuteReader方法,以确保关闭DataReader时相应的连接也被关闭。如果从一个方法返回DataReader,而且不能控制DataReader的相关连接的关闭,则这样做特别有用。

不能在层之间远程访问DataReader。DataReader是为已连接好的数据访问而设计的。

当访问列数据时,使用类型化访问器,例如GetString、GetInt32等。这使你不用将GetValue返回的Object强制转换成特定类型。

一个单一连接每次只能打开一个DataReader。如果想在相同的数据存储区上同时打开两个DataReader,则必须显式创建两个连接,每个DataReader一个。这是ADO.NET为池化连接的使用提供更多控制的一种方法。

在默认情况下,DataReader每次Read时都要将整行加载到内存。这允许在当前行内随机访问列。如果不需要这种随机访问,为了提高性能,则将CommandBehavior.SequentialAccess传递给ExecuteReader调用。这将DataReader的默认行为更改为仅在请求时将数据加载到内存。注意,CommandBehavior.SequentialAccess要求顺序访问返回的列。也就是说,一旦读过返回的列,就不能再读它的值了。

如果已经读取了来自DataReader的数据,但仍然有大量挂起的未读结果,则在关闭DataReader之前先要取消Command。因为取消Command可使服务器放弃这些结果,从而释放服务器的资源。

2.4 随用随关,释放资源

对于C#程序员来说,确保始终关闭Connection和DataReader对象的一个方便的方法就是使用using语句。using语句在离开自己的作用范围时,会自动调用被"使用"的对象的Dispose。例如:

1. string connectionString = "data source=127.0.0.1;Database=codematic;
2. user id=sa;password=";
3. using (SqlConnection myConnection = new SqlConnection(connectionString))
4. {
5. SqlCommand cmd = myConnection.CreateCommand();
6. cmd.CommandText = "SELECT * FROM P_Product";
7. myConnection.Open();
8. using (SqlDataReader dr = cmd.ExecuteReader())
9. {
10. while (dr.Read())
11. {
12. Response.Write(dr.GetInt32(0).ToString()+","+dr.GetString(1)

+"<br>");
13. }
14. }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: