Ado.Net笔记

什么是Ado.Net

它是一种数据访问技术,应用程序可以连接到数据库,并以各种方式来操作其中的数据。一个COM组件库,.Net中数据优先选择的数据访问接口。

ADO:ActiveX Data Objects 早期开发人员用来访问数据的组件。.Net Ado.Net 逐步取代Ado。
他们之间的关系?
Ado.Net 是Ado的升级版,严格上,它们又是俩种截然不同的方式。
技术上:Ado oledb接口 ,基于COM技术,
Ado.Net 拥有自己的接口,基于.Net体系架构。

组成

  • DataSet 非连接的核心组件。独立于任何数据源的数据访问,多种不同的数据源。
  • Data Provider(数据提供程序):用于连接数据库、执行命令、检索结果
    • SQLServer数据提供程序 System.Data.SqlClient命名空间
    • OLEDB的数据提供程序 System.Data.Oledb命名空间
    • ODBC的数据提供程序 System.Data.Odbc命名空间
    • Oracle数据提供程序 System.Data.Oracle命名空间
  • Connection 提供与数据源的连接 SqlConnection
  • Command 执行数据库命令的对象 SqlCommand
  • DataReader 从数据源中提供快速的,只读的数据流 SqlDataReader
  • DataAdapter 提供DataSet对象与数据源的桥梁。Fill Update

SqlConnection介绍

Ado.Net访问数据库的步骤

  • 连接到数据库
  • 打开连接
  • 创建执行命令对象
  • 执行命令
  • 关闭连接

SqlConnection类继承于DbConnection抽象基类,不能被实例化。提供与SQLServer数据库的连接

常用属性

  • Database:要连接数据库名称
  • DataSource:数据源 localhost:ip
  • State:连接状态
  • ConnectionTimeout:
  • state
    • Closed 已关闭
    • Open 打开
    • Connecting 正在连接
    • Executing 正在执行命令
    • Fetching 正在检索
    • broken 连接中断

连接字符串

连接字符串是什么?
字符串,一组被格式化的键值对,数据源在哪里,数据库名,提供什么样访问信任级别,其他相关信息。
格式:一组元素组成,一个元素–键值对,各个元素之间用;隔开。
SQLServer连接字符串

            SqlConnection conn = new SqlConnection();
            conn.ConnectionString = "";
            string connStr = "Data Source=localhost; Initial Catalog=TestNewBase;UserId=sc; Password=ysdsyyn";

Windows身份验证

            SqlConnection conn = new SqlConnection();
            conn.ConnectionString = "";
            string connStr = "Data Source=localhost;Initial Catalog=TestBase;Integrated Security=SSPI";

MySQL

Data Source 数据源; Initial Catalog 数据库名;UserId账号;password密码。
Oracle

Data Source 数据源;UserId 账号;password密码。
Access
Provider=Microsoft.Jet.OLEDB.4.0; DataSource=文件的绝对路径;UserId=admin;Password=1234。

构建连接字符串(连接数据库)

专门的类来构建字符串 DbConnectionStringBuilder 基类 SqlConnectionStringBuilder 程序代码中写连接字符串。
配置文件中配置连接字符串
App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    </startup>
	<connectionStrings>
		<add name="connStr" connectionString="server=localhost; database=TestNewBase;uid=sa; pwd=ysdysyn"
			 providerName="System.Data.SqlClient"/>
	</connectionStrings>
	<appSettings>
		<add key="connStr" value="server=localhost; database=TestNewBase;uid=sa; pwd=ysdysyn"/>
	</appSettings>
</configuration>

cs文件

            SqlConnection conn = new SqlConnection();
            string connStr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
            string connStr = ConfigurationManager.AppSettings["connStr"].ToString();

            conn.ConnectionString = connStr;
            conn.Open();
            conn.Close();

连接池

为什么我们要用连接池?
它非常耗时耗力一件事,有这几个阶段:建立物理通道,服务器初次握手,分析连接字符串,身份验证,运行检查。
可重复利用已连接的连接池

连接池是什么?

优化容器,存放了一定数量的鱼数据库服务器的物理连接。
需要容器里取出一条空闲的连接,而不是创建一条新的连接。
作用 :减少了连接数据库的开销,从而提高了应用程序的性能。
分类:类别区分,同一时刻同一应用程序域可以有多个不同类型的连接池。
什么来标识区分:进程、应用程序域、连接字符串 windows标识、共同组成的签名来标识区分;对同一领域来说,由连接字符串来区分,打开一条连接,如果这条连接的类型签名与现有的连接不匹配,就会创建一个新的连接池,反之则不会创建,他们会共用同一个连接池。
如何分配连接
根据连接请求的类型,找到与它相匹配的连接池,尽力的分配一条空闲的连接。
有空闲的连接,返回这条连接,用完的话,会创建一个新链接添加到连接池中;到达最大连接数时,等待,直至有空闲连接。
移除无效连接
不能真确的连接到数据库服务器的连接,连接池存储的与数据库服务器的链接数量是有限的。无效的连接,我们应当移除。浪费连接池空间,连接池管理器会处理吴小莲姐的移除问题。
回收连接

释放使用完的连接,应当及时关闭或释放,conn对象的CLose Dispose 连接回到连接池。
三个属性

  • Max Pool Size : 最大连接数
  • Min Pool Size:最小连接数
  • Pooling 是否启用连接池 true

SqlCommand介绍及创建

对SQLServer数据库执行的一个T-SQL语句或存储过程
重要属性

  • Connection:SQLCommand对象使用的SQLConnection
  • CommandText:获取或设置要执行的T-SQL语句或存储过程名
  • CommandType:CommandText.Text–执行的是一个sql语句;CommandText.StoredProcedure–执行的是一个存储过程
  • Parameters:SqlCommand对象的命令参数集合 空集合
  • Transaction:获取或者设置要在其中执行的事务。
    创建
  • 创建命令,执行命令的对象,执行命令
  • 命令–T-SQL或存储过程==数据库里已创建好
  • SQLCommand对SQLServer数据库执行的一个T-SQL语句或存储过程
  • SQLCommand对象:Ado.Net中执行数据库命令的对象
  • SQLCommand创建
  • ExecuteNonQuery:返回增改删的行数
  • ExecuteScalar方法:查询出的行数
  • ExecuteReader:查询返回1一个对象:SqlDataReader数据流
    • 如果执行不带参数的ExecuteReader,关闭dr,并不会关闭连接
    • 如果执行带参数的ExecuteReader,关闭dr就会关闭连接,关闭连接也会关闭dr。

SQLParameter

定义:表示SQlCommand对象的参数,或于DataSet中列的映射
常用属性

  • Dbtype参数的sqlDbType(数据类型,数据库的类型)
  • Driection 参数的类型,输入,输出,输入输出,返回值参数
  • ParameterName参数名称
  • Size最大大小 字节为单位
  • value 参数的值
  • Sqlvalue 作为SQL类型的参数的值

参数作用:不带任何条件,不是通过参数传递,拼接SQL,具体的值;拼接SQL容易被注入,转义–防注入
command添加参数的几种方法

  • cmd.Parameters.Add()
  • cmd.Parameters.AddWithValue()
  • cmd.Parameters.AddRange()、

参数使用

输入参数
参数化SQL语句或存储过程,默认使用的参数–输入参数

!以下三种:用在存储过程里
输出参数
output 程序中是可以接收到存储过程里需要返回的值,而不是return
Direction:Output
输入输出参数
output进行标识 它需要传入值,也输出住 而不用return
Driection:InputValue
返回值参数
他不会出现在存储过程中,只可以返回int类型 return返回的值

SqlDataReader介绍

定义:提供一种从SQLServer数据库中读取只进的行流的方式。
特点:快递、轻量级、只读的,遍历访问每一行数据的数据流,向一个方向,一行一行的,不能向后读取,不能修改数据。
缺点:不灵活,只适合数据小的情况,读取数据,一直占用连接。
读取方式:Read()方法返回False时,就表示不再有数据行。
注意:连接对象一直保持Open状态,如果关闭连接,是不能读取数据的。使用完成后,应该马上调用close()关闭,不然Reader对象会一直占用连接的
创建方式:是不能直接构造的,cmd.ExecutdReader()来创建。cmd.ExecuteReader(CommandBehaviour.CloseConnection)–好处,关闭reader对象时,就会自动关闭连接。
读取时尽量使用与数据库字段类型相匹配的方法来取得对应的值,会减少类型不一致而增加类型转换操作性能损耗。
没有读取到末尾就要关闭reader对象时,先调用cmd.Cancel(),然后在调用reader.Close()
cmd.ExecuteReader()获取存储过程的返回值或输出参数,先调用reader.Close(),然后才能获取参数的值。
常用属性

  • Conection:获取与Reader对象相关的SqlConnection
  • FiedCount:当前行中的列数
  • HasRows:reader是否含一行或者多行
  • IsClosed:reader对象是否已关闭 true false
  • Item[int]:列序号,给定列序号的情况,获取指定列的值,dr[1] object
  • Item[string]:列名,获取指定列的值
    常用方法
  • Close():关闭dr
  • GetInt32(序列号):根据数据类型相匹配的方法
  • GetFieldType(i):获取数据类型的Type
  • GetName(序列号):获取指定列的列名
  • GetOrdinal(列名):获取指定列名的序列号
  • Read():使dr前进到下一条记录
  • NextResult()使dr前进到下一个记录

DataTable详解

概念:DataSet:数据在内存中的缓存(数据库)Ado.Net核心组件。DataTable:内存中一个表(数据库中的一个表)。
应用:DataSet中的成员使用,他可独立创建与使用。结合DataAdapter使用。
架构:列和约束来表示。DataColumn列
成员:行,DataRow
构造:DataTable()DataTable(表名)
常用属性

  • Columns:列集合
  • Rows:行的集合
  • Contraints:约束的集合
  • DataSet:DataTable所属的DataSet
  • PrimaryKey:主键(列的数组)
  • TableName:指定表名

方法

  • AcceptChanges():提交更改
  • RejectChanges():回滚更改
  • Clear():清空数据
  • Copy():复制架构和数据
  • Clone():只复制架构,不包含数据
  • Load(IDataReader):通过提供的IDataReader,用某个数据源的值来填充DataTable
  • Merge(DataTable):合并,指定的dt合并到当前的dt里
  • NewRow():创建一个DataRow,与Dt具有相同的架构
  • Reset():将dt重置到最初状态
  • Select():获取dt所有的行的数组(条件,排序)

DataSet详解

概念:DataSet是数据在内存中的缓存–内存中的数据库,DataTable内存数据库中的一个表,Ado.Net的核心组件
成员:一组DataTable组成,DataRelation相互关联,一起实施了数据的完整性
应用:三种:结合DataAdapter使用

  • DataAdapter将数据填充到DataSet中
  • DataAdapter将DataSet中的更改提交到数据库
  • XML文档或文本加载到DataSet中

作用:ds将数据加载到内存中来执行,提高了数据访问的速度,提高了硬盘数据的安全性,程序运行的速度和稳定性
特性:独立性,不依赖于任何数据库,离线和连接。数据视图,数组操作,灵活性。
创建:DataSet()DataSet(名称)

SQLDataAdapter介绍与创建

SqlDataAdapter是什么?
适配器(桥接器):DataSet数据之间用于检索和保存数据的桥梁。
SQLDataAdapter类 --填充DataSet以及更新数据源的一组数据库命令和一个数据库连接
SQLDataAdapter是DataSet和SQLServer之间的桥接器
它是如何提供桥接的?

Fill填充到DataSet里,updata更改提交到数据库 数据保持一致。
SQLconnection SqlCommand一起使用,提高访问速度。
4个主要属性

  • SelectCommand 查询 SqlCommand
  • InsertCommand 插入记录
  • UpdateCommand 更新数据库的记录
  • DeleteCommand 删除记录

SQLDataAdapter对数据的操作也是建立在SqlCommand基础之上的。

4种创建方式


            string connStr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
            string sql = "select * from ProductInfos";
            SqlConnection conn = new SqlConnection(connStr);
            //1,设置SelectCommand
            SqlDataAdapter adapter = new SqlDataAdapter();
            adapter.SelectCommand=new SqlCommand(sql, conn);
            //2,通过SqlCommand对象来实例化一个adapter
            SqlCommand cmd= new SqlCommand(sql, conn);
            SqlDataAdapter adapter1= new SqlDataAdapter(cmd);
            //3,插叙语句和连接对象来实例化一个adapter
            SqlDataAdapter adapter2 = new SqlDataAdapter(sql, conn);
            //4,查询语句和连接字符串,构建一个adapter
            SqlDataAdapter adapter3 = new SqlDataAdapter(sql, connStr);

Adapter与Reader比较

相同:执行查询,将数据读取出来,一个或多个

  • SqlDataReader:提供一种从数据库中读取数据流的方式
  • SqlDataAdapter:DataSet与数据库之间的桥接器 Fill Update

不同的:

性能对比 SqlDataReader SqlDataAdapter
速度
数据量
占用内存
连接状态 一直占用 断开和连接
读取方式 从头读到尾一条一条读,读一条丢一条,即时存储,不灵活, 一次性加载到内存中,任意读取,灵活
是否可读 只读,不能修改 可读可写

不要求随意读取,不修改,数据量小–SqlDataReader,速度快,占用内存小。
可以随意读取,可以修改,数据量大的情况下–SQLDataAdapter,灵活性大,占用空间大,不一直占用连接。

事务

Ado.Net调用数据库事务

事务执行过程:开启,提交,回滚。
插入,故障,并未数据库,维护数据的完整性
Ado.Net如何调用事务–实质:调用一个普通的存储过程–里面的逻辑是一段事务代码
批量导入–数据库事务,不可能传入几千个参数–不具有可行性。

数据访问通用类封装

为什么要封装通用类?
数据交互:增删改查–相同的事:连接
T-SQL命令,Command–执行命令,选择执行方式–得到相应的结果–关闭连接。
我们如果把所有的过程写在一起,整个代码会杂乱无章,不清晰。
改善:一些相同的逻辑–封装起来,通用
作用:代码重利用,提高效率,不在考虑交互过程,逻辑清晰。
DBHelper类的内容规划

  1. 连接钥匙–连接字符串–配置文件–创建连接–连接释放–using()
  2. SqlCommand三种执行方法:
    • 增删改
    • ExecuteNonQuery()执行T-SQL,返回受影响的行数
    • ExecuteScalar()执行查询,返回结果集第一行第一列的值,忽略其他行或列,返回object类型
    • ExecuteReader()-执行查询,生成-SQLdataReader
  3. SQLDataAdapter填充ds,dt
  4. SQLTransaction CommandInfo:T-SQL 参数数组 CommandType //sql

封装类

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;

namespace AdoNetCourse
{
    
    
    public class DBHelper
    {
    
    
        private static readonly string ConnStr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
        SqlConnection connection = null;


        /// <summary>
        /// 执行T-SQL,返回受影响的行数  insert update delete
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="cmdType"></param>
        /// <param name="paras"></param>
        /// <returns></returns>
        public static int ExecuteNonQuery(string sql, int cmdType, params SqlParameter[] paras)
        {
    
    
            int count = 0;
            using (SqlConnection conn = new SqlConnection(ConnStr))
            {
    
    
                SqlCommand cmd = new SqlCommand(sql, conn);
                if (cmdType == 2)
                    cmd.CommandType = CommandType.StoredProcedure;
                if (paras.Length > 0 && paras != null)
                    cmd.Parameters.AddRange(paras);

                conn.Open();
                count = cmd.ExecuteNonQuery();
                conn.Close();
            }
            return count;
        }

        /// <summary>
        /// 执行查询,返回结果集第一行第一列的值,忽略其他行或列,返回object类型
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="cmdType"></param>
        /// <param name="paras"></param>
        /// <returns></returns>
        public static object ExecuteScalar(string sql, int cmdType, params SqlParameter[] paras)
        {
    
    
            object o = null;
            using (SqlConnection conn = new SqlConnection(ConnStr))
            {
    
    
                SqlCommand cmd = new SqlCommand(sql, conn);
                if (cmdType == 2)
                    cmd.CommandType = CommandType.StoredProcedure;
                if (paras.Length > 0 && paras != null)
                    cmd.Parameters.AddRange(paras);

                conn.Open();
                o = cmd.ExecuteScalar();
                conn.Close();
            }
            return o;
        }

        /// <summary>
        /// 执行查询,生成-SQLdataReader
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="cmdType"></param>
        /// <param name="paras"></param>
        /// <returns></returns>
        public static object ExecuteReader(string sql, int cmdType, params SqlParameter[] paras)
        {
    
    
            SqlDataReader dr = null;
            SqlConnection conn = new SqlConnection(ConnStr);

            SqlCommand cmd = new SqlCommand(sql, conn);
            if (cmdType == 2)
                cmd.CommandType = CommandType.StoredProcedure;
            if (paras.Length > 0 && paras != null)
                cmd.Parameters.AddRange(paras);

            try
            {
    
    
                conn.Open();
                dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
            }
            catch (SqlException ex)
            {
    
    
                conn.Close();
                throw new Exception("执行查询异常", ex);
            }

            return dr;
        }



        public static DataTable GetDataTable(string sql, int cmdType, params SqlParameter[] paras)
        {
    
    
            DataTable dt = null;
            using (SqlConnection conn = new SqlConnection(ConnStr))
            {
    
    
                SqlCommand cmd = new SqlCommand(sql, conn);
                if (cmdType == 2)
                    cmd.CommandType = CommandType.StoredProcedure;
                if (paras.Length > 0 && paras != null)
                    cmd.Parameters.AddRange(paras);

                SqlDataAdapter da = new SqlDataAdapter(cmd);
                conn.Open();
                da.Fill(dt);
                conn.Close();
            }
            return dt;
        }

        public static bool ExecuteTrans(List<string> listSQL)
        {
    
    
            using(SqlConnection conn = new SqlConnection(ConnStr))
            {
    
    
                conn.Open();
                SqlTransaction trans = conn.BeginTransaction();
                SqlCommand cmd = conn.CreateCommand();
                cmd.Transaction = trans;
                try
                {
    
    
                    for(int i = 0; i < listSQL.Count; i++)
                    {
    
    
                        cmd.CommandText = listSQL[i];
                        cmd.ExecuteNonQuery();
                    }
                    trans.Commit();
                    return true;
                }
                catch(SqlException ex)
                {
    
    
                    trans.Rollback();
                    throw new Exception("执行事务出现异常",ex);

                }

            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_52473844/article/details/129817989