zoukankan      html  css  js  c++  java
  • ADO.NET 连接方式进行数据访问

    连接到数据源

    连接到数据源需要使用两步:

    1.创建连接字符串

    2.使用Connection通过连接字符串进行连接

    例1:

    //使用连接字符串
    //注意引用System.Data.Common 和 System.Data.SqlClient
    string connectionString = "server=.;database=DataBaseST;uid=sa;pwd=s1s1s1";
    DbConnection connection = new SqlConnection(connectionString);

    一般来说,我们不会在每个页面都自定义一个连接字符串,然后再使用该字符串.如果某天需要修改该连接时,将会非常麻烦,所以我们将该字符串放入web.config,然后通过从该文件中获取连接信息.

    例2:

    web.config中配置如下:

    <connectionStrings>
        <add name="dbstconnectionstring" connectionString="Data Source=.;Initial Catalog=databasest;
                   Persist Security Info=True;User ID=sa;password=s1s1s1" providerName="System.Data.SqlClient"/>
    </connectionStrings>

    页面调用如下:

    //注意引用System.Data.Common
    //注意引用System.Data.SqlClient
    string connectionString = ConfigurationManager.ConnectionStrings["dbstconnectionstring"].ConnectionString;
    DbConnection connection = new SqlConnection(connectionString);

    此处需要注意的是:

      连接字符串中的server,database,uid是必不可少的,如果有密码,则pwd也不可少.

      注意引用命名空间

    可参见以下网站,提供众多连接字符串格式:

    连接字符串

    创建命令

    创建对象使用Command对象.Command对象是一个Sql语句或存储过程的引用.Command对象可以被直接引用.

    如何创建Command对象?见下例:

    //创建Command有以下两种方式
    //方式一
    //  通过Connection创建
    DbCommand cmd1 = connection.CreateCommand();
    
    //方式二
    //  创建Command实例,再制定Connection
    DbCommand cmd2 = new SqlCommand();
    cmd2.Connection = connection;

    Command对象有以下重要属性:

    属性 描述
    CommandType 命令类型.
    值为枚举类型,有以下值:
    Text:Sql脚本命令,默认值.
    StoredProcedure:存储过程
    TableDirect:表的名称(用的比较少)
    CommandText Sql语句或存储过程的名字
    Parameters 命令的参数

    Command对象有以下重要方法:

    方法 描述
    ExecuteScalar 返回一个唯一的值
    ExecuteNonQuery 用于更新或修改数据库结构,返回被影响行数
    ExecuteReader 返回数据行的集合

    执行命令

    通过对Command对象设定CommandType类型和CommandText,我们就可以通过上述方法来执行Command命令.

    我们以下表,表结构如下:

    image

    表中数据如下:

    image

    • 我们首先演示ExecuteScalar方法,该方法用于返回结果集中的第一行的第一列;如果结果集为空,则为空引用.

    请看以下示例:

    string connectionString = ConfigurationManager.ConnectionStrings["dbstconnectionstring"].ConnectionString;
    DbConnection connection = new SqlConnection(connectionString);
    
    connection.Open();
    DbCommand cmd = connection.CreateCommand();
    
    //默认情况,Command对象的CommandType属性为Text
    cmd.CommandText = "select count(*) from Employee";
    
    string result = cmd.ExecuteScalar().ToString();
    Response.Write(result);
    
    connection.Close();
    • 下面再来看ExecuteNonQuery方法的使用,该方法可执行INSERT、DELETE、UPDATE 及 SET 语句等命令.

    看以下示例:

    string connectionString = ConfigurationManager.ConnectionStrings["dbstconnectionstring"].ConnectionString;
    DbConnection connection = new SqlConnection(connectionString);
    
    connection.Open();
    DbCommand cmd = connection.CreateCommand();
    
    //默认情况,Command对象的CommandType属性为Text
    //现在,我们设置Command对象的CommandType属性为StoredProcedure
    cmd.CommandType = CommandType.StoredProcedure;
    
    //此时Command对象的CommandText属性为存储过程名称
    cmd.CommandText = "InsertEmployee";
    
    int result = cmd.ExecuteNonQuery();
    Response.Write(result);
    
    connection.Close();

    使用存储过程InsertEmployee内容如下:

    ALTER PROCEDURE dbo.InsertEmployee
    AS
        /* SET NOCOUNT ON */
        insert into Employee (EmployeeName,EmployeeAge,EmployeeDeparmentID,EmployeeScore)
        values ('周?九?',27,1,85)
        RETURN

    运行后,表内容如下,增加了一条新数据:

    image

    • 最后来看ExecuteReader方法的使用

    ExecuteReader使用Transact-SQL的 sp_executesql 系统存储过程调用命令.

    该方法返回一个DataReader对象.DataReader是一个只读的、前向的数据行的流.

    DataReader对象有以下常用属性和方法:

    属性或方法 类别 描述
    Item 属性  
    Read 方法 Sql语句或存储过程的名字
    GetXXX 方法 获取值,其中XXX指String,Int32等等
    GetValues 方法 一次性获取当前所有的列
    IsDbNull 方法 测试当前值是否为Null
    Close 方法 当Read返回为false时,应及时关闭DataReader,释放连接

    例1:

    string connectionString = ConfigurationManager.ConnectionStrings["dbstconnectionstring"].ConnectionString;
    DbConnection connection = new SqlConnection(connectionString);
    
    connection.Open();
    DbCommand cmd = connection.CreateCommand();
    
    //默认情况,Command对象的CommandType属性为Text
    cmd.CommandText = "select * from Employee";
    
    DbDataReader reader = cmd.ExecuteReader();
    while (reader.Read())
    {
        //reader读取数据时,列从0开始编号,故EmployeeID为第0列,EmployeeName为第1列
        //读取数据时采用了3种方式:
        //  1.因EmployeeName列为string类型,所以可以使用GetString方法
        //  2.采用Item方式
        //  3.采用GetValue方法
        //语句中使用了IsDbNull方法来判断分数栏是否为空
        Response.Write(string.Format("Name:{0}    Age:{1}    Score:{2}<br/>", 
            reader.GetString(1), 
            reader["EmployeeAge"],
            reader.IsDBNull(4) ? "无" : reader.GetValue(4)));
    }
    
    //先关闭Reader
    reader.Close();
    
    //再关闭Connection
    connection.Close();

    DataReader可以返回多个数据集结果,可使用NextResult方法移到下一个结果集,见下例.

    例2:

    protected void Page_Load(object sender, EventArgs e)
    {
        string connectionString = ConfigurationManager.ConnectionStrings["dbstconnectionstring"].ConnectionString;
        DbConnection connection = new SqlConnection(connectionString);
    
        connection.Open();
        DbCommand cmd = connection.CreateCommand();
    
        //默认情况,Command对象的CommandType属性为Text
        cmd.CommandText = "select top 2 * from Employee;select top 3 * from Employee";
    
        DbDataReader reader = cmd.ExecuteReader();
        Read(reader);
    
        Response.Write("<hr>");
        reader.NextResult();
        Read(reader);
    
        //先关闭Reader
        reader.Close();
    
        //再关闭Connection
        connection.Close();
    }
    
    void Read(DbDataReader reader)
    {
        while (reader.Read())
        {
            //reader读取数据时,列从0开始编号,故EmployeeID为第0列,EmployeeName为第1列
            //读取数据时采用了3种方式:
            //  1.因EmployeeName列为string类型,所以可以使用GetString方法
            //  2.采用Item方式
            //  3.采用GetValue方法
            //语句中使用了IsDbNull方法来判断分数栏是否为空
            Response.Write(string.Format("Name:{0}    Age:{1}    Score:{2}<br/>",
                reader.GetString(1),
                reader["EmployeeAge"],
                reader.IsDBNull(4) ? "无" : reader.GetValue(4)));
        }
    }

    结果:

    image 

    使用参数

    • 介绍

    Sql语句和存储过程可以有输入输出参数以及返回值

    例如,我们在添加雇员信息时,雇员信息都是由用户输入进去的,而不是由系统内部设定的.

    • 如何实现?

    使用Command的Parameters可以实现我们向其中添加参数.

    注意:

    参数类型可以由Direction来设置,该属性值为一个枚举类型,取值如下:

    ParameterDirection取值 描述 对应C# 对应SQL
    Input 输入    
    InputOutput 输入输出 ref 对应output
    Output 输出 out
    ReturnValue 返回值    
    • 例子
    string connectionString = ConfigurationManager.ConnectionStrings["dbstconnectionstring"].ConnectionString;
    //注意:
    //  此处换为SqlConnection,原来为DbConnection
    SqlConnection connection = new SqlConnection(connectionString);
    
    //注意:
    //  此处换为SqlCommand,原来为DbCommand
    SqlCommand cmd = connection.CreateCommand();
    
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.CommandText = "InsertEmployee";
    
    //添加参数的几种写法
    cmd.Parameters.Add("@EmployeeName",SqlDbType.NVarChar).Value = "测试用户";
    cmd.Parameters.Add(new SqlParameter("@EmployeeAge", 30));
    
    //推荐使用AddWithValue方法
    cmd.Parameters.AddWithValue("@EmployeeDepartmentID", 1);
    cmd.Parameters.AddWithValue("@EmployeeScore", 95);
    
    cmd.Parameters.Add(new SqlParameter("@outValue", SqlDbType.NVarChar, 20));
    cmd.Parameters["@outValue"].Direction = ParameterDirection.Output;
    
    connection.Open();
    int returnValue= cmd.ExecuteNonQuery();
    Response.Write("ReturnValue:" + returnValue + "<br/>");
    
    string result = cmd.Parameters["@outValue"].Value.ToString();
    Response.Write("outValue:" + result);
    connection.Close();

    存储过程InsertEmployee内容如下:

    ALTER PROCEDURE dbo.InsertEmployee
    (
        @EmployeeName nvarchar(20),
        @EmployeeAge int=null,
        @EmployeeDepartmentID int=null,
        @EmployeeScore int=null,
        @outValue nvarchar(20) output
    )
    
    AS
        /* SET NOCOUNT ON */
        if exists(select * from Employee where EmployeeName=@EmployeeName)
        begin
            set @outValue='用户名重复'
            return
        end
        
        insert into Employee (EmployeeName,EmployeeAge,EmployeeDeparmentID,EmployeeScore)
        values (@EmployeeName,@EmployeeAge,@EmployeeDepartmentID,@EmployeeScore)
        
        set @outValue='成功!'
        
        return

    目前数据库中并没有"测试用户"这样一个用户.

    第一次运行时,结果如下:

    ReturnValue:1
    outValue:成功! 

    第二次运行时:结果如下:

    ReturnValue:-1
    outValue:用户名重复 

    实现事务

    事务是一系列相互关联的任务,作为一个整体成功提交或失败(提交或回滚).

    事务的特性:

      Atomicity(原子):事务或者全部提交,或者全不提交

      Consistency(一致):事务保证了数据的完整性

      Isolation(分离):事务处理了数据操作的并发性

      Durability(持续):即使在事务结束后,发生系统崩溃等灾难性情况,事务涉及的数据操作也将正常保存

    先看使用Sql来实现事务.还是看例子来理解,我们现在新增一个表:Bank.

    表结构如下:

    image

    表内容如下:

    image 

    现在,我们向表中添加一系列的用户,因为CustomerName是主键,所以不能重复.看下例:

    string[] customerList = new string[] { 
            "小张",
            "小王",
            "李四",
            "小赵"
    };
    
    string connectionString = ConfigurationManager.ConnectionStrings["dbstconnectionstring"].ConnectionString;
    SqlConnection connection = new SqlConnection(connectionString);
    connection.Open();
    
    SqlTransaction transaction = connection.BeginTransaction();
    SqlCommand cmd = connection.CreateCommand();
    cmd.Transaction = transaction;
    
    try
    {
        foreach (string customer in customerList)
        {
            cmd.CommandText = "insert into bank(customername,customermoney) values ('" + customer + "',0)";
            cmd.ExecuteNonQuery();
        }
        transaction.Commit();
    }
    catch
    {
        transaction.Rollback();
    }
    finally
    {
        connection.Close();
    }
        }

    在运行代码时,我们打开SqlServer事件查看器,看到以下结果:

    exec sp_reset_connection
    go
    SET TRANSACTION ISOLATION LEVEL READ COMMITTED;BEGIN TRANSACTION
    go
    insert into bank(customername,customermoney) values ('小张',0)
    go
    insert into bank(customername,customermoney) values ('小王',0)
    go
    insert into bank(customername,customermoney) values ('李四',0)
    go
    IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION
    go

    结果是数据表中没有任何数据被增加.

    现在我们将customerList中的"李四"用户去掉.再来看来SqlServer事件查看器中的结果:

    exec sp_reset_connection
    go
    SET TRANSACTION ISOLATION LEVEL READ COMMITTED;BEGIN TRANSACTION
    go
    insert into bank(customername,customermoney) values ('小张',0)
    go
    insert into bank(customername,customermoney) values ('小王',0)
    go
    insert into bank(customername,customermoney) values ('小赵',0)
    go
    COMMIT TRANSACTION
    go

    数据库Customer表的内容如下:

    image

    小结

      • 使用Connection创建数据库连接
      • 使用Command创建命令
      • 使用ExecuteScalar,ExecuteNonQuery,ExecuteReader方法来执行命令
      • 使用DataReader来读取数据
      • 使用Command对象的Parameters属性来添加参数
      • 使用Connection对象来创建Transaction事务
  • 相关阅读:
    02_排版标记
    21_listview展示数据内容回顾
    00_前情回顾
    20_通过listview展示数据库数据_完成
    18_simpleadapter和ArrayAdapter总结
    19_通过listview展示数据库数据_数据库准备数据完成
    前端面试题-url、href、src
    前端面试题-url、href、src
    前端面试题-url、href、src
    这8个方法让你成为最优秀的程序员
  • 原文地址:https://www.cnblogs.com/oneword/p/1823414.html
Copyright © 2011-2022 走看看