黑马程序员-------ADO.NET数据访问

来源:互联网 发布:隆逸优化作品 编辑:程序博客网 时间:2024/05/22 10:37

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>

<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

一、ADO.NET是什么?

    在装了SQLServer服务器的机器上,可以通过SQL Management Studio来操纵数据库并且进行管理数据,实现数据的增删改查等各项功能,但是,不可能任何时候都通过设计器模式来访问数据,当我们要通过应用程序来访问数据时,就要通过ADO.NET来实现,因此,ADO.NET就是一种数据访问技术,是通过应用程序来访问数据库服务器,来获取所需要的数据或者进行操作。

二、ADO.NET基本组成

ADO.NET包含了两个重要的核心组件:数据提供程序和数据集:

1)数据提供程序

基本SQLClient

Connection 用来连接数据库

Command  用来执行SQL语句

DataReader 只读只进的结果集

拿到查询的结果

DataAdapter 封装了上面的3个对象的对象

2)数据集

DataSet 临时数据库

断开数据库的操作

三、ADO.NET数据访问的步骤

(1)数据库的连接

首先要引用命名空间,using System.Data.SqlClient(针对SQLServer数据库)

SqlConnection来进行连接,这时需要用到连接字符串

连接字符串内包括:

1)用SqlServer身份验证登录

server=服务器名称,database=要连接的数据库,user=用户名,password=密码

连接字符串一般包括以上几项内容。

示例:

string connstr = @"server=ZCH-PC\SQLEXPRESS;database=D_test;user=sa;password=123456";

2)windows身份验证登录

Server=服务器名称,database=要连接的数据库,Integrated Security=true;

示例:

string connstr = @"server=ZCH-PC\SQLEXPRESS;database=D_test;Integrated Security";

3)连接字符串的其他写法:

Server的值可以改成ip地址,这样就通过网络访问其他主机上的数据库了。还可以改成.\数据库名来访问本地数据库

Server 还可以用Data source  ,database可以写成initial cataloguser 简写成uid password简写成pwd

例如:string connstr=@”data source=”服务器名;initial catalog =数据库名;uid=sa;pwd=123”;

连接的两种方式:

1)SqlConnection  连接变量名=new  SqlConnection()  ---使用无参数的构造函数来连接

   String  连接字符串=............”;

   conn.ConnectionString=连接字符串;

   连接变量名.Open() ;                       --调用open() 来打开数据库连接

string connstr = @"server=ZCH-PC\SQLEXPRESS;database=D_test;user=sa;password=123456";

SqlConnection conn = new SqlConnection();

conn.ConnectionString = connstr;

conn.Open();

示例:

2)定义连接字符串    String  连接字符串=.............

  SqlConnection  连接变量名=new SqlConnection(连接字符串) --使用有参数的构造函数,写入连接字符串

   连接变量名.Open()

string connstr = @"server=ZCH-PC\SQLEXPRESS;database=D_test;user=sa;password=123456";

SqlConnection conn = new SqlConnection(connstr); 

conn.Open();

不管采用哪个构造函数,最后都要调用Open()方法。

3)如果连接字符串写在了程序中,那么就相当于固定了,如果服务器改变了,就要修改应用程序,这时,为了方便,可以单独新建一个App.config配置文件,写入连接字符串,如果有什么变化,直接修改配置文件即可,不用改动应用程序。

配置文件:App.config

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <connectionStrings>         <addconnectionString="Datasource=ZCH-PC\SQLEXPRESS;database=master;user=sa;password=123456" name="connstr1"/>

  </connectionStrings>   //添加连接字符串

</configuration>

在写入配置文件之后,可以引入该类库。

配置文件的引用:打开要使用字符串的项目,选中“引用”单机右键,选择“添加引用”,在弹出的对话框中,选择“.net”,找到“System.Configuration”后,点击确定。这时,打开Program.cs,在项目中,加入命名空间的引用,就可以使用该命名空间下的ConfigurationManager类进行配置文件的引用了。

在配置文件中,可以写入多个连接字符串

4)连接成功之后,就可以执行各项操作了,这是有一个属性state可以查看连接的状态。

(2)Close()与 Dispose()

凡是有Dispose()方法的类型,需要在执行后dispose(),一般访问非托管资源的时候,才会实现dispose接口。

因为数据库的连接要占用很大的资源,而数据库是稀有资源,因此,当程序执行完之后,要释放资源,因此,要用到close() dispose()

Close():数据库的连接关闭,但是资源还被占用着,因此关闭之后还可以在调用OPEN()打开连接。

Dispose():数据库资源的释放,相当于销毁了一个连接,调用了Dispose()之后不能再打开了。

为了方便,使用Using可以自动的释放资源。

用法:Using (连接的对象){要执行的语句}

{}内的语句块执行结束后,自动调用dispose(),因此,自动释放()内的连接对象。

示例:

static void Main(string[] args)

        {

            int result = 0;

            string sql = "select count(*) from [dbo].[Student]";

string connstr = ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;

            using (SqlConnection conn = new SqlConnection(connstr))

            {

                using (SqlCommand cmd = new SqlCommand(sql,conn))

                {

                    if (conn.State == ConnectionState.Closed)

                    {

                        try

                        {

                            conn.Open();

                            result = (int)cmd.ExecuteScalar();

                        }

                        catch(Exception e)

                        {

                            Console.WriteLine(e.Message);

                        }

                    }                

                }     

            }

            Console.WriteLine("查询到的结果是:{0}", result);

            Console.ReadKey();                   

        }

    }

(3)输入SQL语句

写入SQL语句需要用到的类是SqlCommand

(1)用法:SqlCommand  变量名=new SqlCommand();

示例:

SqlCommand 类的构造方法有三种重载,最常用的是传入sql语句字符串和加入要连接的实例:string sql = "select count(*) from [dbo].[Student]";

string connstr=ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;

SqlConnection conn = new SqlConnection();           

conn.ConnectionString =connstr;

SqlCommand cmd = new SqlCommand(sql,conn); //使用了两个参数的构造方法        

conn.Open();

2SqlCommand 变量名=new SqlCommand SQL语句字符串,连接对象)

也可以使用无参数的Sqlcommand,这是需要调用对象的connection来传入要连接的对象和调用对象的commandText来传入查询语句。

string sql = "select count(*) from [dbo].[Student";

string connstr=ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;

SqlConnection conn = new SqlConnection();

conn.ConnectionString =connstr;

SqlCommand cmd = new SqlCommand();    //使用了无参数的构造函数。

cmd.Connection = conn;                  //需要调用这样的方法来赋值

cmd.CommandText = sql;

conn.Open();

(4)Sql语句执行,返回结果:用SqlCommand 的对象来调用下面的方法。

传入SQL命令后,需要来执行,这就用到了执行方法:

1)ExecuteScalar()  //用作查询只返回一行一列结果,单值查询

示例:int result=0;

string sql = "select count(*) from [dbo].[StudentShiWan]"; //该条语句执行后返回一个值

string connstr=ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;

qlConnection conn = new SqlConnection();           

conn.ConnectionString =connstr;

SqlCommand cmd = new SqlCommand(sql,conn);           

conn.Open();

result =(int)cmd.ExecuteScalar(); //执行查询,因为结果是object类型,需要拆箱操作

Console.WriteLine("结果是:{0}",result);

Console.ReadKey();

2)ExecuteNonQuery()//不返回结果集,只执行命令,返回受影响的行数(执行行数)一般不用做查询,执行插入,删除修改等操作。

ExecuteNonQuery用法示例:

static void Main(string[] args)

        {

            int num;     //定义一个int类型的变量,用作接收受影响行数的

string connstr=ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;

           SqlConnection conn = new SqlConnection(connstr);

            using(conn)    //使用using()来执行完语句后释放连接对象

            {

                using (SqlCommand cmd = new SqlCommand())

                {

                    try

                    {

                        if (conn.State == ConnectionState.Closed)

                        {

                         conn.Open();      //调用open()方法打开数据库连接

                 cmd.CommandText = "update[dbo].[studentinfomation] set address='上海'";

                         num = cmd.ExecuteNonQuery();   //使用了“执行”命令

                            Console.WriteLine("{0}行受影响!!~~", num);

                        }

                    }

                    catch (Exception e)

                    {

                        Console.WriteLine(e.Message);

                    }

                }

            }

            Console.ReadKey();

因为ExecuteNonQuery()的执行是不返回结果集的,所以,一般用作数据库的增删改,不用做查询,这个例子中,只要修改一下SQL语句,就可以返回增加,修改,查询的受影响的行数了。

3ExecuteReader()  //用作查询,返回DataReader对象。

1、在执行了ExecuteReader()方法之后,要定义一个DataReader 实例来接收它的值,

DataReader 实例名 =ExecuteReader();

2、虽然返回了一个DataReader类型的对象,它只返回一些数据信息,但数据本身不再对象里,要通过调用其他方法来获取数据。

3DataReader 的实例在读取数据时,是一条一条的来读取的,当查询到数据时,数据在数据库内存中,每调用一次read()方法,内存的指针向下移一次,来读取每一行数据。

重要的属性:

1)HasRow;布尔类型了值,如果有值返回true,如果没有值,返回false,能够做出有没有读到数据的判断。

2)FieldCount:返回字段的总数

3)RecondsAffected::当用ExecuteReader来执行增,删,改的操作时,返回受影响的行数

常用的方法:

1)read():获取每一行数据。//可以传入要读取的列名或者列序号来获取指定列。

2)Dispose()该实例有dispose()方法,因此,要在运行结束时释放资源,可放入using()里使用。

3)GetString(int i):在调用时,传入列的序号,就可以返回该列的字符串。

4)GetNameint i):传入列的序号,获取列的名称。

5)GetOrdinarystring s):传入列的名称,获取列的序号。

调用ExecuteReader()方法的示例:

...................................................................

 static void Main(string[] args)

        {

            Console.WindowWidth = 170;

            Console.WindowHeight = 44;

            string sql ="select * from mybook";    //要查询的sql语句字符串

    string connstr = ConfigurationManager.ConnectionStrings["connstr"].ConnectionString; //读取配置文件中的连接字符串。

            using (SqlConnection conn = new SqlConnection(connstr))  //创建连接对象

            {

                if (conn.State == ConnectionState.Closed)  //判断数据库连接状态,如果是     

                {                                   //关闭状态就开发

                    try{

                    conn.Open();

                    using (SqlCommand cmd = new SqlCommand(sql, conn))/                   {                                                   //创建sqlcommand对象。

 

                        using (SqlDataReader reader = cmd.ExecuteReader())

                        {                           //执行sql并返回sqldatareader

                            if (reader.HasRows)

                            {                      //判断是否有数据

                                while (reader.Read())  //如果有数据就获取一行的数据

                                {

                                    for (int i = 0; i < reader.FieldCount; i++)

                                    {

                                        object o = reader[i];//获取每个字段的数据并

                                        Console.Write(o.ToString()+"\t");//打印出来

                                    }

                                    Console.WriteLine();

                                }

                            }

                        }

                    }

                        

                    }

                    catch(Exception e)

                    {

                        Console.WriteLine(e.Message);

                    }

                }              

            }

}

总结获取数据的步骤:

1)首先,调用ExecuteReader()方法返回sqldatareader实例

1)用hasrow属性判断查询结果是否存在数据

2)如果存在,就循环调用read()方法来获取每一行数据

3)利用索引,或者GetString(),GetValue(),或者通过循环FieldCount;获取每一行、每个字段或者指定字段的值。

四、DateSet离线数据库

DateSet就是在与数据库断开的情况下,进行访问数据,这是因为,把数据导入到dateset的临时内存中,不过,不适合在有大量的数据的情况先使用,因为,这会加重本地内存的负担。

实现离线数据库访问有两个很重要的类

(1)DateSet把数据库中的数据一次性导入到DateSet从而,就可以断开数据库的连接。

(2)SqlDataAdapter该类的一个实例通过调用fill()方法,把数据填充到dataset中。

填充后的数据集包括的内容:

一个数据库中可以有多张表,因此,一个数据集也可以有多张表。

不仅包含表,还有每张表的行属性,列属性等

DataTable 类代表数据库的一张表

DataRow类代表数据库中,一张表的一行数据

DataColumn类代表数据库中,一张表的一列数据

示例:

static void Main(string[] args)

        {

            Console.WindowHeight = 44;

            Console.WindowWidth = 170;

          string  connstr=ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;

          string sql = "select * from mybook;select * from MyBooks"; //sql连接字符串与查询语句

          DataSet dataset = new DataSet("book");                //新建离线数据集

          try

          {

              using (dataset)

              {

          SqlDataAdapter adapter = new SqlDataAdapter(sql, connstr);            

                        using (adapter)                 //新建SqlDataAdapter

                  {                                  //并传入sql语句,和连接字符串

                      adapter.Fill(dataset);      //SqlDataAdapter对象调用Fill()填充Dataset

                      DataTable dtmybook = dataset.Tables[0]; //把第一个表赋给DataTable

                      for (int i = 0; i < dtmybook.Rows.Count; i++)  //的实例

                      {                               //通过循环遍历每一行并获取数据

                          DataRow row = dtmybook.Rows[i];

                          for (int j = 0; j < dtmybook.Columns.Count; j++) //通过循环遍历没一

                          {                                       //列数据

                              Console.Write(row[j]+"\t");            //打印每行每列数据

                          }

                          Console.WriteLine();

                      }

                  }

              }

          }

          catch (Exception ex)

          {

              Console.WriteLine(ex.Message);

          }

          Console.ReadKey();

        }

五、参数化数据查询

由于SQL注入漏洞等安全问题,不在使用拼接字符串的方法来实现SQL语句来进行查询,而是通过传入参数来执行SQL语句。

用到的类SqlPrarmeter 

查询SQL语句方式:

Select 要查询的字段名 from 表名 where 条件=@参数”

例如:Select  price from Book where bookname=”@bookname” ;

再通过SqlCommand 对象,把参数加进去。

例如:SqlCommand  cmd =new SqlCommand();

cmd.Parameters.Add( SqlParameter类型对象)

通过这样的参数传入之后,在调用一些执行的方法来进行数据库操作:

示例:下面是一个执行SQL插入数据的例子:(只有部分代码:)

 string user = txtname.Text.Trim();

 string pwd = txtpwd.Text.Trim();

String sql=string.Format("insert into UserLogin (username,userpassword) values(@username,@userpassword)");  //定义了两个参数

SqlParameter [] sqls=new SqlParameter []{new SqlParameter("@username",user),new SqlParameter ("@userpassword",pwd)};            //SqlParameter类型的数组,定义了参数和相关的值

            try

            {

                int result = Register(sql, sqls); //Register()是双线下面的方法

                MessageBox.Show(string.Format("成功插入了{0}条数据", result));

            }

================================================================================

public static int Register(string sql, SqlParameter[] sqlparams)//要调用该方法,要传入两个类型的

        {                                         //参数,返回受影响的行数

            int result=-1;

            try

            {

                using (SqlConnection conn = new SqlConnection(connstr))

                {

                    conn.Open();

                    using (SqlCommand cmd = new SqlCommand(sql, conn))

                    {

                        foreach (SqlParameter sqlpara in sqlparams)

                        {

                            cmd.Parameters.Add(sqlpara); //Sqlcommand对象把参数一个一个

                        }                            //的加入进去

                        result = cmd.ExecuteNonQuery();  

                    }

                }

            }

            catch(Exception ex)

            {

                throw new Exception(ex.Message);

            }

            return result;

        }

 

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>

<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

0 0
原创粉丝点击