第一章 ado.net
- 1 ado.net架构
ado.net其实本质上是一组提供与数据库交互和操作的类库。
1、ado.net数据提供程序
数据提供程序是一组用于访问特定数据库,执行sql命令,并获取最终结果的ado.net类。Ado.net有以下几种数据库提供程序类:
(1)connectin:连接数据库
(2)command:执行sql命令和存储过程
(3)datareader:读取结果,即查询结果有很多条。
(4)dataadapter:包含以上三条命令的功能。
2、ado.net重点
(1)ado.net提供程序模型是可扩展的,即可第三方开发自定义数据提供程序。
.net4.0提供了 sqlserver提供程序,odbc提供程序,ole db提供程序,oracle提供程序(.net4.0以后不提供oralce提供程序,用oralce自已发布的odp.net提供程序)
(2)ado.net是标准化的,虽然提供了松散的模型,不同的数据类型使用不同的数据提供程序,但他们都继承于同样的接口和基类,保证了每个不同的数据提供程序以同样的方式工作并显示相同的属性和方法。所以方法名和使用方法都一样。如open(),close()等核心方法。这样可以在更换数据库后,不用重新开发程序,直接修改ado.net即可。
3、基于ado.net的类
(1)基于连接的对象:如connection,command,datareader,dataadapter类。
(2)基于内容的对象:dataset,datacolumn,datarow,datarelation类。它们完全和数据源独立。
这几种类的命令空间在system.data中。需要应用这些类的方法时,需要先导入命名空间。
如:要调用sqlserver数据库,就导入system.data.sqlclient命名空间中。
处理数据库的步骤
->连接数据库 //connectin
->初始化SQL语句
->准备Command对象
->打开连接
->执行查询
- 2 connection类
1、 连接字符串
Server //指定数据库服务器名和实例名
Database//指定要连接的数据库名
Uid和pwd //登录数据库服务器的帐号和密码
Integrated security=sspi //用windowsauthentication验证。
例:
[email protected]"server=.\sqlexpress;"+"database=test;"+"uid=sa;"+"pwd=zjt71305"; //@的作用是,后面的\不作转义符,做为字符使用。,注意,引号里的分号不能少。
[email protected]"server=.\sqlexpress;database=test;integratedsecurity=SSPI";//也可以用这种格式。这里是用windows验证。如果是远程服务器,就要指定ip地址。
SqlConnection con=newSqlConnection(source); //新建一个sqlconnection对象,把字符串作参数初始化,就连接了数据库了。
con.Open(); //打开数据库
con.close() //关闭数据库。数据库在用的时候才开,不用就关掉,不然占用资源太大。
2、 高效的使用连接
当服务器打开,有时会忘记关闭时,会耗很多资源。
(1) try …catch….finall
try
{
Con.open()
}
Catch()
{
}
Finally
{
Con.close(); //保证在任何情况下都会关闭数据库连接。
}
(2)using //实现了disable
using (con)
{
con.Open(); //保证在任何情况下,只要退出using语句就会自动关闭数据库。
}
- 3 command类
三种执行命令
ExcuteNonQuery()//一般用于update,insert,delete语句的执行。返回受影响的记录数。即非查询语句执行。
ExcuteScalar()//该方法返回查询结果第一行第一列的值,如果没有数据,则返回NULL!适用于只返回一个值的存储过程,和用聚合函数返回值的。用于返回一个值的查询语句。
ExcuteReader()//用于返回多条记录的查询语句。
例(1) excutenonquery()
[email protected]"server=.\sqlexpress;database=test;integrated security=SSPI";
SqlConnection con=new SqlConnection(source)
Using(con)
{
string insert = "insert intoshopping values(100008,‘啤酒‘,200,3.5,100004,‘量大‘)"; //准备sql语句
SqlCommand cmd = newSqlCommand(insert, con);//把SQL语句作为一个参数传递给command类的构造函数。前面的是SQL语句,后面是连接字符串对象。准备command对象
//Sqlcommand cmd=con.command(sql); //也可以这种写法。
Using(cmd) //cmd也要using起来。
{
Con.open(); //打开数据库
Int ros=Cmd.excutenonquery(); //执行查询。有返回值,并赋值给ros。定义了命令,一定要执行才有用。
}
}
Console.writeline(ros);
例(2)excutescalar()
string str=ConfigurationManager.ConnectionStrings["str"].ConnectionString; //应用程序文件
SqlConnection con=newSqlConnection(str);
using(con)
{
con.Open();
SqlCommand cmd=con.CreateCommand();
using(cmd)
{
cmd.CommandText="selectcount(*) from shopping where snumber<@number";
cmd.CommandType=CommandType.Text; //这是默认的,可以省略。
SqlParameter para1=newSqlParameter("@number",SqlDbType.Int);
//新建一个sqlparameter实例,并且定义变量的类型和长度。
para1.Value=50; //给变量赋值。
cmd.Parameters.Add(para1); //把值添加到语句中。
//cmd.Parameters.Add(new SqlParameter("@name",50)); //这一句相当于上面三句
int i=(int)cmd.ExecuteScalar(); //执行查询。
Console.WriteLine(i);
Console.ReadKey();
}
}
例(3) excutereader()
主要是查询多条数据。
例:
string str=ConfigurationManager.ConnectionStrings["Str"].ConnectionString;
//把连接字符串定义到了配置应用文件中了。
SqlConnection con = newSqlConnection(str);
using (con)
{
con.Open();
SqlCommand com = con.CreateCommand();
using (com)
{
com.CommandText="usp_kucun"; //调用存储过程。如果是普通语句就直接写sql语句。
com.CommandType = CommandType.StoredProcedure; //存储过程类型。另有文本类型和表格类型,分别对应于sql语句,和excel表。
com.Parameters.Add(newSqlParameter("@number",50)); //给参数赋值。
SqlDataReader read =com.ExecuteReader(); //注意此处,后面是com.excutereader(),不是 new sqldatareader();
using (read)
{
while (read.Read())//此方法返回一个布尔类型,初始时指针在所查询数据条之前,不指向任何一条数据,然后每调用一次此方法,指针就下移一条,只要没移到最后一条之后就一直返回true。如果移到最后一条数据之后,就返回false。所以用此方法用来判断和遍历数据。
{
string sname = read.GetString(0); //get方法即是获取查询后表的某一列的值,0代表第一列。以此类推。因为第一列是商品名,所以这里是string类型。有很多种GET方法,数据类型一定要与表中的类型一致。
int snumber = read.GetInt32(1);
Console.WriteLine("名称是{0},库存数是{1}", sname, snumber);
Console.ReadKey();
}
}
}
}
1.3、 datareader类
读取查询到的结果
1、基本用法:
sqldatareader read=cmd.excutereader(); //后面是cmd.executereader(),新建一个sqldatareader实例 。
using(read)
{
read.read(); //此方法返回一个布尔类型,初始时指针在所查询数据条之前,不指向任何一条数据,然后每调用一次此方法,指针就下移一条,只要没移到最后一条之后就一直返回true。如果移到最后一条数据之后,就返回false。所以用此方法用来判断和遍历数据。
sqldatareader有好多方法和属性。
While(reader.read()) //当不是最后一条之后,所以一直返回为真,就一直循环。
{
String name=Read.getstring(0); //返回第查询到数据的第一列的值,并且会显示所有行的第一列。
Int number=Read.getint32(1) //显示查询数据第二列的值
}
}。
2、常用方法:
(1)GetOrdinal:获取指定列名的列序号(索引号),使用这个方法可以把经常变动的列进行固定
intname=dr.GetOrdinal("name"); //通过列名来获取当前列的索引号
(2)GetName: 获取列名,参数为指定列名的序列号,返回string
stringcolumnName=dr.GetName(name);//通过列名所处的索引号来获取列名名称
(3)IsDBNull:判断当前读取的数据是否为Null,返回类型为Bool
dr.IsDBNull(coContractID)?"NULL":dr.GetInt32(coContractID).ToString();
(4)NextResult:当查询为批处理查询时,使用这个方法去读取下一个结果集,返回值为Bool,如果存在多个结果集,则为 true;否则为 false。
(5)Read:读取数据
3、常用属性
(1)HasRow:判断是否包含一行或多行,也就是判断有没有数据,返回类型为Bool。
(2)FieldCount:获取读取的列数,返回类型为Int。
(2) IsClosed:判断读取的数据流是否关闭。
1.4 sql 参数化防注入(SqlParameter类的的用法)
1、 常用方法和属性:
(1)属性
ParameterName:设置参数名
Value:给参数设置值
Size:设置参数字节最大大小
SqlDbType:参数在SQL中的类型
(2)方法:
(1)AddWithValue:直接增加参数名和值。
(2)Add:添加参数的类型和长度等。
(3)AddRange:添加数组参数。
给命令对象添加参数法:
id =1;
string Name="lui";
cmd.CommandText="insert into TUserLogin values(@Id,@Name)";
//上条语句中直接在sql语句中写添加的参数名,不论参数类型都是如此.
第一步:sqlParameter para=new SqlParameter("@Id",SqlDbType.int,4);//生成一个名字为@Id的参数,必须以@开头表示是添加的参数,并设置其类型长度,类型长度与数据库中对应字段相同
第二步:para.Value=Id;//给参数赋值,即把id这个值赋给了@id这个参数。
//以上两步可以合成一步如:
Sqlparameterpara=new sqlparameter(“@id”,id)//后面是直接给id变量赋值
第三步:cmd.prameters.Add(para);//必须把参数变量添加到命令对象中去。
//以下类似
Cmd.parameters.add(newsqlparameter(“@name”,name)); //也可以把上面三步合并成一步执行。
1.5配置字符串
1、在项目 中新增一个应用程序配置文件,增加如下XML代码。
<configuration>
<connectionStrings>
<add name="sql"connectionString[email protected]"server=.\sqlexpress;database=test;uid=sa;pwd=zjt71305" /> <!--关键字区分大小写-->
</connectionStrings>
</configuration>
2、在项目中添加System.Configuration引用,并在主程序中引用命名空间system.confguration
3、在主程序中增加以下语句即可
string str=ConfigurationManager.ConnectionStrings["Sql"].ConnectionString;//这里的sql是在xml里定义的连接字符串的名字,可以随便取。
1.6、sqlhelp
即把ado.net的各种查询封装到类中。
classsqlhelper
{
privatestaticstring str=ConfigurationManager.ConnectionStrings["str"].ConnectionString;
publicstaticint ExecuteNonyQuery(string sql )
{
SqlConnection con = newSqlConnection(str);
using (con)
{
con.Open();
SqlCommand cmd = con.CreateCommand();
using (cmd)
{
cmd.CommandText = sql;
return cmd.ExecuteNonQuery();
}
}
}
publicstaticobject ExecuteScalar(string sql,paramsSqlParameter[] nums)
{
SqlConnection con = newSqlConnection(str);
using (con)
{
con.Open();
SqlCommand cmd = newSqlCommand(sql, con);
using (cmd)
{
cmd.Parameters.AddRange(nums);
return cmd.ExecuteScalar();
}
}
publicstaticvoid ExecutReader(string sql,paramsSqlParameter [] nums)
{
SqlConnection con = newSqlConnection(str);
using (con)
{
con.Open();
SqlCommand cmd = newSqlCommand(sql, con);
using(cmd)
{
SqlDataReader read = cmd.ExecuteReader();
while (read.Read())
{
}
}
}
- 1.7dataset
String [email protected]
1.8sqldapeter
批量数据读取器。一次性查询一批数据出来后,存放到数据库的内存池中,而不是直接返给用户。然后用sqldataapeter一次读一条出来,直到读完。