数据访问技术

一、Ado.net介绍

Ado.net是数据访问技术的统称。在C#中,我们主要通过Ado.net技术来实现程序和数据库的交互。

ADO.NET主要5大对象:

1.1 Connection:连接池对象,用来与数据库建立连接。

里面包含:SqlConnectionOledbConnectionOdbcConnectionOracleConnection

SqlConnection对象用于连接Sql Server数据库

OledbConnection对象用于连接Access数据库

OracleConnection对象用于连接Oracle数据库

OdbcConnection对象用于连接ODBC数据源

同理,下面的CommandDataReaderDataAdapter对象也分别对应不同的数据库,提供了这样4种类型的对象。

 

1.2 Command:命令对象,用来执行sql命令并返回结果。同理我们针对sql server数据库时,需要使用SqlCommand对象。其他类似。

 

1.3 DataReader:数据读取流,用来逐行读取查询语句返回的结果集。(执行select语句时使用)

 

1.4 DataAdapter:数据适配器,用来将查询语句的结果集填充到内存中。(执行select语句时使用)

 

1.5 DataSet:数据集,用来存储数据的容器。其内部结构类似于数据库,可以看成是虚拟的数据库,由多个表组成。表中由数据行和列组成。通常执行查询语句时,为了方便访问查询语句的结果集。会使用DataAdapter对象将结果填充到DataSet中。方便我们在程序中对数据进行操作。

 

 

二、下面我们以操作Sql Server数据库为例,把经典5步及容易犯的错误标注一下:

首先需要引用命名空间:System.Data.SqlClient;

 

//首先确定要执行的sql语句,实际上无外乎4种,添加、修改、删除、查询

string sql="Insert/Update/Delete/select"; 

注:一般在写sql语句的过程中,对于刚接触的同学,建议先在sql server工具中编写语句,确定语法正确后,在将语句拷贝到程序中。另外切记不要掉单引号。不管是添加、修改、删除、查询时,凡是语句中包含字符串或者日期类型的数据,必须给数据加上单引号。如:insert into users(name,pwd,age,birthday) values(‘张三’,’123’,20,’2012-2-10’),其他数据类型的数据可以不加单引号。

 

操作数据库的五个步骤:

1.1 创建连接池对象

SqlConnection conn=new SqlConnection("server=数据库所在机器ip地址;database=数据库名;uid=登录用户名;pwd=登录密码");

注:在编写连接字符串时,连接本机数据库时,服务器ip地址可以使用.,写法为:

Server=.;database=数据库名;uid=用户名;pwd=密码

另外也可以使用windows身份验证,即不需要指定用户名和密码,写法为:

server=.; database=数据库名;Integrated Security=true

 

1.2 打开连接池对象

conn.Open();

注:必须打开连接池对象后,才能执行命令操作,程序运行时,如果在这句代码处报错,通常只有一种可能,就是连接字符串错误。请根据错误信息仔细检查连接字符串。

 

1.3 创建命令对象

SqlCommand cmd=new SqlCommand(sql,conn);

 

1.4 执行命令操作(执行语句并返回相应结果的过程)

cmd.ExecuteNonQuery(); 

注:该方法专用于执行添加、修改、删除的SQL语句,返回增删改语句执行成功的行数。通常判断返回的行数大于0,则操作成功,否则失败

cmd.ExecuteScalar();    

注:该方法适用于查询语句,但只会返回查询语句结果集中首行首列的数据,且返回后需要进行类型转换。

cmd.ExecuteReader();   

注:该方法适用于查询语句,结果集为多行多列时。但返回的并不是结果集,返回的是DataReader对象。需要使用该对象的Read()方法逐行去读取结果集中的数据

 

在程序运行时,如果在这句代码处报错,那错误的原因也只有一种可能,就是SQL语句错了。请好好检查SQL语句,如果检查不出来,建议调试跟踪出具体的sql语句,然后放在sql server工具中,让工具告诉你哪里错了。

 

1.5 关闭连接池对象

conn.Close();

注:切记一定要关闭,在C# 中,默认能够使用的连接池对象为100个,也就是说如果每次创建连接池对象并且打开后,都不关闭的话,该连接池对象没有真正销毁,一直被占用着。到了100个后,将无法再创建新的连接池对象。将无法操作数据库。

 

 

三、示例参考

一般在多个窗体中都需要操作同一个数据库,每次都需要去编写连接字符串,这样代码重复性比较高,而且后期数据库密码更改后,维护起来比较麻烦。所以通常会创建一个类,在类中定义公共静态变量来保存连接字符串。在窗体中通过类名.变量名来读取。通常类名约定为DBHelper,在类中编写如下代码:

Class DBHelper

{

Public static string ConnStr=” server=数据库所在机器ip地址;database=数据库名;uid=登录用户名;pwd=登录密码

}

 

1、执行添加、修改、删除语句时。

string sql="Insert/Update/Delete ";

1)、创建连接池对象

SqlConnection conn=new SqlConnection(DBHelper.ConnStr); //读取DBHelper类中的连接字符串

2)、打开连接池对象

conn.Open();

3)、创建命令对象

SqlCommand cmd=new SqlCommand(sql,conn);

4)、执行命令操作(执行语句并返回相应结果的过程)

int rows=cmd.ExecuteNonQuery(); 

5)、关闭连接池对象

conn.Close();

if(rows>0)//根据返回的执行成功的行数进行判断,如果大于0,代表添加/修改/删除成功,否则失败
{

MessageBox.Show(“操作成功!”);

}

else

{

MessageBox.Show(“操作失败!”);

}

 

2、执行查询语句时

 

2.1当查询语句返回结果为一个数据时,即单行单列的值。比如:

Select count(*) from 表名或者是Select name from 表名 where id=

这样一类的语句,通常返回结果只有一个数据时。

string sql="Select …";

1)、创建连接池对象

SqlConnection conn=new SqlConnection(DBHelper.ConnStr);

2)、打开连接池对象

conn.Open();

3)、创建命令对象

SqlCommand cmd=new SqlCommand(sql,conn);

4)、执行命令操作(执行语句并返回相应结果的过程)

Object obj=cmd.ExecuteScalar(); 

注意:该方法的返回类型为object类型,目前还没学习这个类型,但我们可以将这个类型理解为一种通用类型,但在使用时,需要进行类型转换。也就是说根据你查询语句的返回结果,如果返回的是int类型,那就需要转换为int类型;如果为字符串那就转换为字符串类型。

5)、关闭连接池对象

conn.Close();

 

//对返回值进行类型转换,一般在转换前,建议判断是否为null。代码参考如:

If(obj!=null)
{

//类型转换,如果是int,则

Int a=Convert.ToInt32(obj);

//如果是string,则

String a=obj.ToString(); //以此类推。所以需要根据select 语句返回的结果来确定这里该转换的目标类型

}

 

2.2查询多行多列的结果时,可以使用两种方式:

一:使用DataReader对象一行一行读取结果集中的数据

DataReader对象的特点:

1、只进、只读的数据读取流

2、用来逐行读取查询语句结果集中的数据。

3、在读取期间,连接池对象必须保持打开状态。

 

注:该对象只是负责读取数据,本身并不包括数据

Read():读取下一行数据,如果有数据,返回true,否则返回false

Close():读取完后,关闭对象。

 

使用范例:

string sql="Select …";

1)、创建连接池对象

SqlConnection conn=new SqlConnection(DBHelper.ConnStr);

2)、打开连接池对象

conn.Open();

3)、创建命令对象

SqlCommand cmd=new SqlCommand(sql,conn);

4)、执行操作

//返回数据读取流

SqlDataReader reader= cmd.ExecuteReader();

//判断读取流是否为null

if (reader != null)

{

      //逐行读取结果集中的每一行数据

      while (reader.Read())

      {

            //根据字段名读取reader中某字段的值,并转换为字符串

            string loginid = reader["id"].ToString();            

      }

      //关闭DataReader对象

      reader.Close();

}

conn.Close();

 

二、使用DataAdapter将结果集中地数据一次性的放在数据容器DataSet中,方便以后读取。

DataAdapter:数据适配器,主要用来将结果集填充到DataSet

DataSet:数据容器,就像虚拟的数据库一样,由多个数据表组成。

使用范例:

1、创建连接池对象

SqlConnection conn=new SqlConnection(DBHelper.ConnStr);

2、打开连接池对象

conn.Open();

3、创建命令对象

SqlCommand cmd=new SqlCommand(sql,conn);

4、执行命令操作(执行语句并返回相应结果的过程)

//创建数据适配器来读取cmd对象的返回结果集

SqlDataAdapter da=new SqlDataAdapter(cmd);

//创建容器

DataSet ds=new Dataset();

//将数据放在容器中

da.Fill(ds);

5、关闭连接池对象

conn.Close();

 

结束语:实际上操作数据库,其中有几步总是不变的:创建连接池、打开连接池、创建命令对象、关闭连接池,这几步写法基本是固定死的。真正在变的就2块:要执行的sql语句,和执行的操作。执行的操作主要为2大块,要么是增加、修改、删除,都统一使用ExecuteNonQuery方法;要么是查询,查询时有三种处理方式,返回结果为一个数据时,直接使用ExecuteScalar方法;当返回结果比较多时,可以使用ExecuteReader方法,也可以使用DataAdapter配合DataSet。大家可以根据自己的习惯去取舍。

posted @ 2015-03-19 16:19  酸酸の柚子  阅读(294)  评论(2编辑  收藏  举报