C#操作sqlserver数据库
in C#SQL with 0 comment
Read:243

C#操作sqlserver数据库

in C#SQL with 0 comment

写C#一般用的是宇宙最强IDE——vs。访问数据库,使用微软提供的ADO.NET技术,是负责数据访问的类库子集。ADO.NET可以在数据源完全断开的情况下对数进行修改,并且将数据的更新情况返回数据源,这样就大大减少了由于数据链接过多而引起的服务器资源占用。


.NET数据操作核心对象

.NET中有操作数据库四个核心对象

Connection对象 建立与特定数据源的连接
Command对象 对数据源执行命令
DataReader对象 从数据源中读取只进只读的数据流
DataAdapter对象 使用数据源填充DataSet并支持更新

ADO.NET提供两种方式访问数据库

非断开式访问:在整个操作过程中需要和数据库保持连接。优势:是一种轻量级的方式,性能更好
断开式访问:只需要在执行数据库命令时才保持连接,命令执行完毕将查询到的数据缓存到内存以后,就断开连接。优势:不占用数据库的连接资源,并可以实现随机访问


数据访问概念

使用ADO.NET检索出数据库中的数据,与将水库中的水利用抽水机和管道抽取出来很相似。数据库类似于水库,存储了大量的数据。Connection对象类似伸入水中的进水笼头,保持与水的接触,只有它与水“连接”,其他对象才可以抽到水。Command对象则类似于抽水机,为抽水提供动力和执行方法,将水提供给上面的输水管。DataAdapter对象和DataReader对象则类似于输水管,担任着水的传输任务,并起着桥梁的作用。DataAdapter对象是一根输水管,通过发动机将水库中的水输送至水池中进行缓存。DataReader对象也是一根输水管,和DataAdapter对象不同的是,DataReader不将水输送至水池中缓存,而是直接单向地将水输送至需要用水的用户或田地中,所以它比需要在水池里中转的情况速度更快。DataSet对象则是缓存水的大水池,即使撤掉抽水装置(断开连接),也可以保持水的供应,这就是利用DataAdapter对象和DataSet数据集断开式访问数据库,这也正是ADO.NET的核心。

操作数据库首先需要连接数据库,连接数据库又需要连接字符串,vs自带生成连接字符串。 点击视图——服务器资源管理器

QQ截图20190213152457.png
右键数据连接——添加连接——然后选择相应的数据库
QQ截图20190213152535.png
填写服务器名,验证方式,数据库名
QQ截图20190213152630.png
最后在右下角得到一窜连接字符串
QQ截图20190213152659.png

操作sqlserver数据库需要导入命名空间

using System.Data.SqlClient;

最好是把数据库操作的方法全部封装到一个类里面

Connection数据库连接对象

//创建sql数据库连接对象,参数为连接字符串
public static SqlConnection con=new SqlConnection("Data Source=.;Initial Catalog=DBTASK;User ID=sa;Password=123456");

Connection对象常用的方法.Open()打开来连接和.Close()关闭连接
当数据库的状态时关闭时,可以用Open()打开

Connection对象有一个属性State,用于指示连接对象的状态,枚举类型。大概有以下值:
Broken与数据库的连接中断,可以先关闭连接后再打开。Closed数据库连接处于关闭状态。Connecting连接对象正在与数据库进行连接。Executing连接对象正在执行命令。Fetching连接对象正在检索数据

Ps:使用完数据库记得关闭连接,不要占用服务器连接资源

Command执行命令对象

//实例化执行命令对象,传入参数有两个,第一个传入sql命令语句,第二个传入connection连接对象
SqlCommand com = new SqlCommand(sql, con);

ExecuteNonQuery()执行数据库命令的方法,并返回受影响的行数

//声明i等于数据库受影响行数,如果i>0就成功了
int i = com.ExecuteNonQuery();

ExecuteScalar()执行查询命令,返回结果集中首行首列的值,只返回一个值,可以用于聚合函数

//返回的时object类型,需要类型转换
int max ==(int)com.ExecuteScalar();

同一个command对象,可以多次使用,只要设置不同的sql命令就可以了。
上面的commannd实例化是简写。实例化参数分别是CommandText属性Connection属性,可以分别单独设置。

//改变了上面的command对象的执行sql命令
com.CommandText=newSql

ExecuteReader()数据读取,返回DataReader对象。
它提供了一个只读只进的数据读取器,用于从查询结果中读取数据,它每次只能读取一行数据,并且在读取过程中,必须保持连接打开状态。

//读取了数据保存在dr里面,n行,需要遍历出来
//括号里面的参数可以不填,意思是当遍历完DataReader对象过后,关闭DataReader对象的同时,也关闭了数据库访问连接。这个参数要引用 using System.Data;
DataReader dr=com.ExecuteReader(CommandBehavior.CloseConnection);
//遍历读取每行数据,检索到数据了就返回true,没有检索到数据返回false
while(dr.Read())
   {
      //索引可以是数字,或者数据库里面的列名
      Object ob = dr[0];
      //或者使用Get系列方法转换类型,其他转换方法也可以
      int id =dr.GetInt32(0);
    }
dr.Close();//记得读完了关闭DataReader对象

DataSet数据集

DataSet对象是创建在内存中的集合对象,类似于在内存中创建的一个小型数据库。当应用程序需要检索数据库中的数据时,可以将检索到的数据加载到DataSet中,DataSet在本地内存中为应用程序提供了待用数据的缓存,它还有维护数据更新的功能,在应用程序重新连接时将更新发送回数据库。

DataSet用于缓存从数据源检索的数据,它具有两个重要的特征:
1.编程模型与数据源独立。
2.支持离线访问。

DataSet的结构与SQL Server数据库的结构非常相似。SQL Server数据库中存在多个表,每个表由行和列组成。DataSet中也包含一个或多个数据表,所有数据表构成了数据表集合(DataTableCollection),其中,每个数据表都是一个DataTable对象。每个数据表又是由数据行和数据列组成,所有的数据行构成了数据行集合(DataRowCollection),其中每个数据行都是一个DataRow对象。同理,所有的数据列构成了数据列集合(DataColumnCollection),每个数据列都是一个DataColumn对象。

数据集DataSet的工作原理:首先客户端连接到数据库,索引到了一些值,把这些值放在客户端的DataSet数据集里面,就可以关闭数据库连接了,数据都复制了一份了DataSet里面,直接操作数据集,需要修改保存数据的时候,再连接数据库,把修改后的数据集返回给数据库修改。DataSet相当于数据库的缓存,映射。断开式访问。

创建数据集需要引入Data命名空间

using System.Data;

创建数据集

//创建数据集
DataSet ds =new DataSet();
//数据集创建好了会有一个默认名称
string name=ds.DataSetName;
//不想要默认名称,可以设置构造函数的参数
ds=new DataSet("NewName");

DataAdapter数据适配器

DataAdapter对象用于填充数据集DataSet和更新数据库,可以将其看作连接DataSet与数据库的桥梁,通过它来获取或更新数据。
有两个常用的方法,Fill填充数据和Update更新数据
填充数据

//创建SqlDataAdapter对象,两个参数,一个sql命令,一个数据库连接对象
SqlDataAdapter ad=new SqlDataAdapter(SQLString,con);
//用Fill()方法填充数据到DataSet数据集对象ds里面,并给填充的表取名为tableName
ad.Fill(ds,"tableName");
//Fill()方法可以直接填充到DataTable对象里面
DataTable table=new DataTable();//需要引入命名空间using System.Data;
ad.Fill(table);
//获取ds数据集对象里面指定名字或者索引的表,里面的指定索引的行,里面的指定索引或者名字的列里面的内容
ds.Tables["tableName"].Rows[0]["id"];//Rows[][]二维数组获取数据库表第几行第几列的值,列可以用数据库同名列名
table.Rows[0][1];//通过DataTable对象获取第一行第二列的值
//Rows就获取了所有的行,同理Columns所有列,Count获取所有行的数量
ds.Tables["tableName"].Rows.Count;

更新数据

//给DataSet里面的DataTable表里面的数据附加新的值
table.Rows[0]["name"]="新名字";
//把DataTable里面的新数据更新回数据库
//ad.Update(table);
//但是这样无法更新回去,因为我们创建DataAdapter对象的时候,传入的参数为sql查询语句,所以他没有更新删除的能力。跟新之前我们要赋予它这些能力才能更新。
//创建CommandBuilder对象,生成更新数据库的相关命令,传入DataAdapter对象作为参数
SqlCommandBuilder builder=new SqlCommandBuilder(ad);//现在DataAdapter对象有了修改数据等功能
ad.Update(table);//现在就可以更新成功了
//Update()函数的参数和Fill差不多。可以时DataSet对象,可以实DataTable对象,可以实DataSet对象加上指定表名

安全

当访问数据库的数据,都需要查询sql,但是sql语句里面的值,很多时候是占位符需要格式化的。比如:

string sql =string.Format("select * from table where age>{0} and age<{1}",50,30);

上面这种写法容易被sql注入

保证安全的查询数据库有很多种办法,举例一种:
一般我们都是把查询数据库的方法写到一个函数里面,需要传入函数的参数一定有sql语句,因为这个不是固定的。
那么我们可以在方法上增加两个形参

//第一个sql命令的类型,是个枚举值,第二个传入的sql命令的参数
CommandType cmdType, params SqlParameter[] cmdParms

我们新加了这两个形参,那么sql语句的写法也要改变

//不用Format格式化字符串了,把所有的参数都换成`@+参数名`
string sql="select * from table where id=@ID and name=@NAME and pwd=@PWD";

对应的函数里面也要增加一些东西

//设置Command对象的类型
cmd.CommandType = cmdType;
//遍历输入的参数,Command对象添加参数
if (cmdParms != null) {
    foreach (SqlParameter parm in cmdParms)
        cmd.Parameters.Add(parm);
    }

传入实参的写法

//new SqlParameter(sql的参数名,值)
函数名(sql,CommandType.text,new SqlParameter("ID",10086),new SqlParameter("NAME","张三"),new SqlParameter("PWD","abc123"));

如果对你有帮助,打钱

赞赏



Responses