当前位置: 首页 > news >正文

第三阶段数据库-2:数据库连接

1_ADO.NET

(1)ADO.NET的名称起源于ADO(ActiveX Data Objects),是一个COM组件库,用于在microsoft技术中访问数据。之所以使用ADO.NET名称,是因为Microsoft希望表明,这是在NET编程环境中优先使用的数据访问接口。

ADO.NET可让开发人员以一致的方式【存取资料来源】(例如 SQL Server 与 XML),以及透过 OLE DB 和 ODBC 所公开的资料来源。资料共用的消费者应用程序可使用ado.net 来连接至这些资料来源,并且撷取、处理及更新其中所含的资料。

(2)OLE 全称 Object Link and embed,即对象连接与嵌入。

ODBC全称Open Database Connectivity,开放数据库连接。

Java语言中连接数据库使用JDBC技术。

2_ADO.Net的类库

(1)DbConnection类(抽象类) ==数据库连接对象,针对所有的数据库

c#想和哪种数据库连接,数据库的提供商实现C#版的驱动程序,连接器需要实现下面的抽象类 DbConnection, DbCommand ,DbDataReader ,DbParameter

c#中已经实现了Sql的的驱动程序: SqlConnection, SqlCommand, SqlDataReader, SqlParameter

(2)Connection 类:用于创建与数据库的连接。

和数据库交互,必须连接它。连接帮助指明数据库服务器、数据库名字、用户名、密码,和连接数据库所需要的其它参数。Connection对象会被Command对象使用,这样就能够知道是在哪个数据源上面执行命令。

与数据库交互的过程意味着必须指明想要执行的操作。这是依靠Command对象执行的。开发人员使用Command对象来发送SQL语句给数据库。Command对象使用Connection对象来指出与哪个数据源进行连接。开发人员能够单独使用Command对象来直接执行命令,或者将一个Command对象的引用传递给DataAdapter,它保存了一组能够操作下面描述的一组数据的命令

(3)Command对象:用于执行SQL语句或存储过程。

成功与数据建立连接后,就可以用Command对象来执行查询、修改、插入、删除等命令;Command对象常用的方法有ExecuteReader()方法、ExecuteScalar()方法和ExecuteNonQuery()方法;插入数据可用ExecuteNonQuery()方法来执行插入命令。

(4)DataReader类:用于以只读、只进的方式从数据库中读取数据

许多数据操作要求开发人员只是读取一串数据。DataReader对象允许开发人员获得从Command对象的SELECT语句得到的结果。考虑性能的因素,从DataReader返回的数据都是快速的且只是“向前”的数据流。这意味着开发人员只能按照一定的顺序从数据流中取出数据。这对于速度来说是有好处的,但是如果开发人员需要操作数据,更好的办法是使用DataSet。

(5)DataSet对象:用于在DataSet和数据库之间传输数据

DataSet对象是数据在内存中的表示形式。它包括多个DataTable对象,而DataTable包含列和行,就象一个普通的数据库中的表。开发人员甚至能够定义表之间的关系来创建主从关系(parent-child relationships)。DataSet是在特定的场景下使用――帮助管理内存中的数据并支持对数据的断开操作的。DataSet是被所有Data Providers使用的对象,因此它并不像Data Provider一样需要特别的前缀

(6)DataAdapter类:数据的容器,可以包含多个数据表。

某些时候开发人员使用的数据主要是只读的,并且开发人员很少需要将其改变至底层的数据源。同样一些情况要求在内存中缓存数据,以此来减少并不改变的数据被数据库调用的次数。DataAdapter通过断开模型来帮助开发人员方便的完成对以上情况的处理。当在一单批次的对数据库的读写操作的持续的改变返回至数据库的时候,DataAdapter 填充(fill)DataSet对象。DataAadapter包含对连接对象以及当对数据库进行读取或者写入的时候自动的打开或者关闭连接的引用。另外,DataAdapter包含对数据的SELECT、INSERT、UPDATE和DELETE操作的Command对象引用。开发人员将为DataSet中的每一个Table都定义DataAadapter,它将为开发人员照顾所有与数据库的连接。所以开发人员将做的工作是告诉DataAdapter什么时候装载或者写入到数据库。

(7)NuGet 是网络上程序集的市场,此市场可以上传 下载第三方的程序集,需要依赖网络,微软把Sql Server的驱动程序内嵌到了C#语言中,操作Sql Server数据库可以直接使用,操作其他的数据库需要先从NuGet上下载到本地,然后再引用

3_利用App.Config配置文件信息

(1)App.config app===>application 应用程序,config===>配置文件

appsettings.json文件中,可以通过各种配置提供程序进行访问和管理。appSettings是一个常用于存储应用程序配置信息的功能,如数据库连接字符串、API密钥或其他配置参数。

(2)将来应用程序中使用的配置信息都可以通过配置文件配置;配置文件配置的信息在发生修改的后,应用程序不需要重新编译

(3)配置数据库连接字符串

<connectionStrings><!-- providerName="System.Data.SqlClient" 用于指定数据库提供程序--><add name="connString" connectionString="server=.,1433;database=db_frist;uid=sa;pwd=Jiao123456@" providerName="System.Data.SqlClient"/>
</connectionStrings>

(4)API密钥或其他配置参数

 <appSettings><add key="AESKEY" value="123456789abcdefg"/><add key="DESKEY" value="12345678"/><add key="AES" value="EncryptTool.AESHelper"/><add key="DES" value="EncryptTool.DESHelper"/></appSettings>

(5)读取配置信息:

  • 首先右键添加引用System.Configuration,使用using 引入命名空间

  • 使用ConfigurationManager对配置文件进行访问,通过.引用访问的标签

  • ConnectionString:设置或获取连接的字符串

private string connectionString = ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString ;
private string value = ConfigurationManager.AppSettings["AES"].ToString() ;

(6)类的成员理论上没有顺序之分,但是养成良好习惯,给他一个放置顺序,方便后期维护

放置顺序:1.私有字段 2.事件 3.构造函数 4.属性 5.方法 6.析构函数

4_数据库操作

(1)实例化数据库连接对象时需要传入一个字符串,用于表示连接的数据库以及名称,密码等信息

  • server 数据库服务名称 可以直接写一个.表示本机,如果端口号是默认的1433可以省略端口号

  • database: 数据库服务中数据库名称

  • 验证方法:有Sql Server验证和Windows身份验证

    • Sql Server验证:uid指定管理 sa(super administrator)超级管理员 pwd:密码

    • Windows身份验证,User ID=sa;password=密码

连接数据库的字符串,将来维护代码不方便,可以把字符串转移到App.config

string connectionString = "server=.,1433;database=db_frist;uid=sa;pwd=Jiao123456@";
string connectionString = "server=.,1433;database=db_frist;User Id=sa;PassWord=Jiao123456@"

5_数据库连接

(1)和数据库建立连接方法1

  • 1.实例化数据库连接对象,打开数据库连接 使用SqlConnection类

  • 2.操作数据库,对数据库进行增删改查,使用Command 类,专门操作数据库,依赖于Connection,必须把sql语句和SqlCommection(连接对象)建立连接

    Execute 执行命令:有两种情况;1.返回影响的行数(Insert,Update,Delete返回行数) 2.返回结果集(Select)使用SqlDataReader实例存储返回的对象

  • 3.实例化一个 DataTable数据表,并将读取到的数据加载到表中

  • 4.关闭数据库连接

//1.实例化数据库连接对象
SqlConnection connection = new SqlConnection(connectionString);
//打开数据库连接connection.Open();
//2.操作数据库 必须把sql语句和SqlCommection(连接对象)建立连接
string sqlString = "select * from Students";
//写法1:
SqlCommand sqlCommand = new SqlCommand(sqlString, connection);
//写法2:
SqlCommand sqlCommand= sqlConnection.CreateCommand();
sqlCommand.CommandText = sql;
//写法3:
SqlCommand sqlCommand = new SqlCommand();
sqlCommand.CommandText = sql;
sqlCommand.Connection= sqlConnection;//执行命令,把命令返回给结果集SqlDataReader dataReader =sqlCommand.ExecuteReader();
//3.dataSet 数据集 一个数据集中可以有多个数据表
DataTable dt = new DataTable();
//Load将读取到的表加载到表中
dt.Load(dataReader);
dataGridView1.DataSource = dt;
//4.关闭数据库连接
connection.Close();

(2)注意:使用上述sqlString拼接会有“sql注入”的风险,建议借助SqlParmeter可以解决sql注入风险,SQL注入‌是一种通过操纵用户输入数据篡改数据库查询语句的攻击方式,可导致数据泄露、系统破坏等严重后果,其核心防御策略包括参数化查询和输入验证。

sql参数的命名约定 :@开头,SqlDbType 是sql参数在数据库的数据类型,Size是sql参数在数据库中的数据类型的长度

查询界面如下

以下是一个完整的客户信息查询方法

private void BindDatagridView1()
{//1.实例化数据库连接对象SqlConnection connection = new SqlConnection(connectionString);//打开数据库连接connection.Open();//string sqlString = "select * from Students";SqlParameter[] sqlParameters = new SqlParameter[]{new SqlParameter("@aaa",SqlDbType.VarChar),new SqlParameter("@AgeStart",SqlDbType.Int),new SqlParameter("@AgeEnd",SqlDbType.Int),new SqlParameter("@Sex",SqlDbType.Bit),new SqlParameter("@BirthdayStart",SqlDbType.DateTime),new SqlParameter("@BirthdayEnd",SqlDbType.DateTime),};//给参数赋值sqlParameters[0].Value = $"%{txtStuName.Text}%";sqlParameters[1].Value = nudAgeStart.Value;sqlParameters[2].Value = nudAgeEnd.Value ;sqlParameters[3].Value = cbbSex.SelectedValue;Console.WriteLine(dtpBirthdayStart.Value);Console.WriteLine(dtpBirthdayStart.Text);sqlParameters[4].Value = dtpBirthdayStart.Value.ToString("yyyy-MM-dd")+" 00:00:00";sqlParameters[5].Value = dtpBirthdayEnd.Value.ToString("yyyy-MM-dd") + " 23:59:59";//为什么要拼接1=1?//方式sql在没有任何条件的时候保存  1=1 一直返回truestring sqlstr = $"select * from Students where 1=1";if (!string.IsNullOrWhiteSpace(txtStuName.Text)){//添加 空格sqlstr += " and StuName like @stuName";}if (nudAgeStart.Value>0){sqlstr += " and StuAge>=@AgeStart";}if (nudAgeEnd.Value > 0){sqlstr += " and StuAge<=@AgeEnd";}if (cbbSex.SelectedValue.ToString()!= "-1"){sqlstr += " and StuSex=@Sex";}//不输入 空if (!string.IsNullOrWhiteSpace(dtpBirthdayStart.Text)){//添加 空格sqlstr += " and Birthday>=@BirthdayStart";}if (!string.IsNullOrWhiteSpace(dtpBirthdayEnd.Text)){//添加 空格sqlstr += " and Birthday<=@BirthdayEnd";} //2.操作数据库 必须把sql语句和SqlCommection(连接对象)建立连接SqlCommand sqlCommand = new SqlCommand(sqlString, connection);sqlCommand.Parameters.Clear();//清空命名使用的参数sqlCommand.Parameters.AddRange(sqlParameters);//添加//Execute 执行命令,把命令返回给结果集,两种情况//1.返回影响的行数(Insert,Update Delete 返回的都是行数)//2.返回结果集(Select返回结果集)//执行命名,把命令返回的结果集存储SqlDataReaderSqlDataReader dataReader =sqlCommand.ExecuteReader();//3.dataSet 数据集 一个数据集中可以有多个数据表DataTable dt = new DataTable();//Load将读取到的表加载到表中dt.Load(dataReader);dataGridView1.DataSource = dt;//4.关闭数据库连接connection.Close();
}

(3)在创建数据库连接对象是可以使用using,不需要手动关闭

注意,在使用SqlParameter创建sql参数时可以不定义数据类型,将数据传入,但是定义sql参数时候 设置类型 否则生成的sql类型可能不准确

以下是另一个完整数据查询方法

private void BindDatagridView2()
{using (SqlConnection sqlConnection = new SqlConnection(connectionString)){sqlConnection.Open();//建议: 定义sql参数时候 设置类型 否则生成的sql类型可能不准确SqlParameter[] sqlParameters = new SqlParameter[]{new SqlParameter("@aaa",$"%{txtStuName.Text}%"),new SqlParameter("@AgeStart",nudAgeStart.Value),new SqlParameter("@AgeEnd",nudAgeEnd.Value),new SqlParameter("@Sex",cbbSex.SelectedValue),new SqlParameter("@BirthdayStart",dtpBirthdayStart.Value.ToString("yyyy-MM-dd") + " 00:00:00"),new SqlParameter("@BirthdayEnd",dtpBirthdayEnd.Value.ToString("yyyy-MM-dd") + " 23:59:59"),};string sqlstr = $"select * from Students where 1=1 and ";if (!string.IsNullOrWhiteSpace(txtStuName.Text)){//添加 空格sqlstr += " and StuName like @stuName";}if (nudAgeStart.Value>0){sqlstr += " and StuAge>=@AgeStart";}if (nudAgeEnd.Value > 0){sqlstr += " and StuAge<=@AgeEnd";}if (cbbSex.SelectedValue.ToString()!= "-1"){sqlstr += " and StuSex=@Sex";}//不输入 空if (!string.IsNullOrWhiteSpace(dtpBirthdayStart.Text)){//添加 空格sqlstr += " and Birthday>=@BirthdayStart";}if (!string.IsNullOrWhiteSpace(dtpBirthdayEnd.Text)){//添加 空格sqlstr += " and Birthday<=@BirthdayEnd";} SqlCommand sqlCommand = new SqlCommand();sqlCommand.CommandText = sqlstr;//相当于SqlCommand的第一个参数sqlCommand.Connection = sqlConnection;//相当于SqlCommand的第二个参数//把sql参数sqlCommand绑定到一起  才可以让sqlCommand对应的sql语句使用参数sqlCommand.Parameters.Clear();//清空命名使用的参数sqlCommand.Parameters.AddRange(sqlParameters);//添加//SqlDataAdapter 是链接数据库和DataSet数据集之间的一个桥梁, 数据适配器(充电器)//SqlDataAdapter 想要和数据库建立链接  需要和SqlCommand链接即可SqlDataAdapter adapter = new SqlDataAdapter(sqlCommand);//定义数据集 ds  如果sql语句返回多个结果集的时候 ds中就会生成多个DataTable//ds中的每个表示 默认名称  Table  Table1  Table2......DataSet ds = new DataSet();//把适配器 "另外一头"获取的数据填充到ds上//Fill() 第二个参数 就是DataTable的表名 表明可以自定义,但是建议和真实的表明一直 或不填写adapter.Fill(ds,"abc");//ds.Tables[0]; 取出数据集中第一张表// dataGridView1.DataSource = ds.Tables[0];dataGridView1.DataSource = ds.Tables["abc"];}
}

(4)第二步,命令执行 返回一个SqlDataReader 可以不把DataReader中的数据存到dataTable中,而是直接读取DataReader中的数据

两种读取的方式 reader.GetXXX() reader[index|列名]

注意: 在设计表的时候 可以为null的列 ,在获取值的时候要先判断

using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{if (sqlConnection.State != ConnectionState.Open)sqlConnection.Open();SqlParameter sqlParameter = new SqlParameter("@Id", SqlDbType.Int);sqlParameter.Value = this.edidId;string sql = "select * from Students where Id=@Id";SqlCommand sqlCommand = new SqlCommand(sql, sqlConnection);sqlCommand.Parameters.Clear();//清空命名使用的参数sqlCommand.Parameters.Add(sqlParameter);//添加//命令执行 返回一个SqlDataReader 不再把DataReader中的数据存到dataTable中//而是直接读取DataReader中的数据//两种读取的方式 reader.GetXXX() reader[index|列名]//注意: 在设计表的时候 可以为null的列 ,在获取值的时候要先判断SqlDataReader reader =   sqlCommand.ExecuteReader();if (reader.Read()){txtStuName.Text=  reader["StuName"].ToString();nudAge.Text = reader["StuAge"].ToString();//IsDBNull 判断当前列的数据是否为null 返回值bool 如果为null返回trueif (reader.IsDBNull(3)){cbbSex.SelectedValue = -1;}else{cbbSex.SelectedValue = (bool)reader["StuSex"] ? 1 :0;}//DBNull.Value  表示数据库中的控制 当数据库中某个字段为空的时候 就会返回一个DBNull.Value   ===> nullif (reader["Birthday"]==DBNull.Value) tpBirthday.Value=DateTime.Now;else   dtpBirthday.Value = (DateTime)reader["Birthday"];}
}

6_获取数据库中值与页面显示值得匹配

(1)例如上述界面的性别一栏

//创建Sex类,用于存储信息
internal class Sex
{public string Name {  get; set; }public int value { get; set; }
}
//创建下拉菜单显示方法
public static void BindCbbSex(ComboBox cbbSex)
{cbbSex.DataSource = new List<Sex> {new Sex(){ Name="全部",value=-1},new Sex(){ Name="男",value=1},new Sex(){ Name="女",value=0},};cbbSex.DisplayMember="Name";//设置下拉框显示的内容  给用户看的cbbSex.ValueMember="Value";//设置下拉框被选择的时候获取的内容  程序获取的 cbbSex.SelectedValue获取的
}
//在主方法中调用显示方法
BindCbbSex(cbbSex);

(2)清空DateTimerPicker控件的方法

  • 1.首先将控件的Format属性设置为Custom(自定义的)

  • 2.设置DateTimerPicker控件的值改变时发生的事件

  • 3.设置清空按钮事件

  • 在初始化页面的时候设置dateTimerPicker1.CustomFormat = " ";可以在页面刚开始时就设置为空

//2.设置事件
private void dateTimerPicker1_ValueChanged(object sender, EventArgs e)
{//设置格式dateTimerPicker1.CustomFormat = "yyyy-MM-dd";
}
//3.设置按钮事件
private void button1_Click(object sender, EventArgs e)
{dateTimerPicker1.CustomFormat = " ";
}
http://www.dtcms.com/a/339878.html

相关文章:

  • [超表面论文快讯-200]PNAS-超表面辅助的多模态量子成像-南京大学祝世宁院士/新国立仇成伟院士团队
  • 警惕可变参数构造函数无限递归
  • Day13_【DataFrame数据组合join合并】【案例】
  • 让模型不再忽视少数类:MixUp、CutMix、Focal Loss三种技术解决数据不平衡问题
  • RabbitMQ:SpringAMQP Direct Exchange(直连型交换机)
  • RabbitMQ:SpringAMQP 入门案例
  • Flink on Native K8S安装部署
  • 3.Kotlin 集合 Set 所有方法
  • es9.0.1语义检索简单示例
  • 颠覆性进化:OpenAI正式发布GPT-5,AI大模型进入“超级智能”时代
  • InnoDB为什么使用B+树实现索引?
  • 神经网络拆解:用Excel模拟手写数字识别
  • Flume学习笔记
  • OR+DBLINK的关联SQL优化思路
  • Transformer中的编码器和解码器是什么?
  • LLMs之RL之GSPO:《Group Sequence Policy Optimization》翻译与解读
  • 高校数字化转型实战:破解数据孤岛、构建智能指标体系与AI落地路径
  • 数据清理后续
  • 低功耗模式
  • Java配置文件
  • Consul- acl机制!
  • 01-Docker-简介、安装与使用
  • Linux学习-通信(信号,共享内存)
  • C++实现教务管理系统,文件操作账户密码登录(附源码)
  • gitlab、jenkins等应用集成ldap
  • AI学习之DeepSeek本地化部署
  • 数据结构-栈和队列
  • Go语言并发编程 ----- sync包
  • Js逆向案例 Scrape Spa2(Webpack自吐)
  • 2020年EAAI SCI1区TOP,基于ORPFOA算法的多无人机在线变化任务路径规划,深度解析+性能实测