黑马程序员_ADO.NET学习知识总结
来源:互联网 发布:英雄无敌2 mac 编辑:程序博客网 时间:2024/05/07 12:25
---------------------- Windows Phone 7手机开发、.Net培训、期待与您交流! ----------------------
ADO.NET 我现在单单的理解为用来对数据库进行操作的一种机制
数据库的连接
建立数据库连接需要引用System.Data.SqlClient;指令
ADO.Net通过SqlConnection类创建到SQL Server的链接,
执行非查询T-SQL语句
SqlCommand ExecuteScalar()方法 用于返回第一行、第一列的数据
SqlDataReader ExecuteReader 执行有多行结果集
ExecuteScalar()方法 用于返回第一行、第一列的数据
连接中所用到的SqlDataReader ,SqlCommand等实例都继承了IDispose接口
对于数据库来说,连接是非常宝贵的资源,所以用完了一定要close,dispose
用using是因为在执行完语句之后它会自动关闭(自动调用Dispose)
Close() 关闭后还能打开 Dispose() 直接撤销,不能再打开
SqlConnection、FileStream等的Dispose内部都会做这样的判断:判断有没有close,如果没有close就先close再Dispose
SqlConnection数据库连接代码:
一种,用户实例登陆(非视频中老师用的数据库连接字符串),不需要项目内嵌mdf文件
在VS里边用Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True
如果用添加用户实例登陆会验证失败,VS好像不支持自带SQL Server用户登陆(这只是我觉得,因为就登陆这弄了两天,怎样都不成功,用windows身份验证就OK)
不过这种连接数据库字符串貌似不能被配置文件识别,所以,还是乖乖的按老师教的用。
public class MyDataBaseService { /// <summary> /// 获取数据库连接 /// </summary> /// <returns></returns> private static SqlConnection GetConn() { SqlConnection conn = new SqlConnection(); //创建数据库连接 string connStr = "server=sky-dong-pc;uid=sa;pwd=sa;database=PersonBank"; //server=sky-dong-pc为连接数据库所用的计算机名 uid为账号 pwd为密码 database为所要连接的数据库 conn.ConnectionString = connStr; conn.Open(); //打开数据库 return conn; } }
另一种,windows身份验证(老师所讲的),项目内嵌mdf文件形式,会有些麻烦,而且好些代码不知道是干什么
在连接数据库之前需要将这段代码在WinFrom程序中放在main函数中(如果不加这段代码,更改数据库数据 它改的是Debug文件下得数据库,而不是所操作的数据库)
string dataDir = AppDomain.CurrentDomain.BaseDirectory; if (dataDir.EndsWith(@"bin\Debug\") || dataDir.EndsWith(@"bin\Release")) { dataDir = System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName; AppDomain.CurrentDomain.SetData("DataDirectory",dataDir); }
然后将方法一中的
string connStr = "server=sky-dong-pc;uid=sa;pwd=sa;database=PersonBank";
改为
"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True“
Database1.mdf问连接数据库文件,其他都一样
ADO.NET程序有两段非常重要的代码
SqlCommand SqlDataReader
using (SqlConnection conn = new SqlConnection(connStr)) //创建数据库连接 { conn.Open(); using (SqlCommand cmd = conn.CreateCommand()) //创建一个查询对象 { cmd.CommandText = "select * from promary"; //查询语句 using (SqlDataReader read = cmd.ExecuteReader()) //返回多个结果集 { while (read.Read()) { ProvinceItem item = new ProvinceItem(); //定义的ProvinceItem 类,里边有Id和Name两个属性 item.Id = read.GetInt32(read.GetOrdinal("proID")); //readerde GetString、GetInt32等方法只接受整数参数,也就是序号, 用GetOrdinal方法根据列名动态得到序号 item.Name = read.GetString(read.GetOrdinal("proName")); cmbSheng.Items.Add(item); } } } }
Prarmeters,防止漏洞参数化查询
让用户输入用户名,密码时如果SQL语句写成
cmd.CommandText="select count(*) from T_Users where UserName='"+username+"'";, password='"+password+"'时输入密码就可能造成漏洞参数化 输入1‘or ’1‘ = ’1 也可以登陆成功
为了防止,则需要将用户输入的参数加到Prarmeters,然后由Prarmeters进行传值
Prarmeters用法:
cmd.CommandText="select count(*) from T_Users where UserName=@UN and password=@P";
cmd.parameters.Add(new SqlParameters("UN",username));
cmd.parameters.Add(new SqlParameters("P",username));
using(SqlCommand cmd = conn.CreateCommand()){ cmd.CommandText="select count(*) from T_Users where UserName=@UN and password=@P"; //如果直接写成cmd.CommandText="select count(*) from T_Users where UserName='"+username+"', password='"+password+"'"; //输入密码就可能造成漏洞参数化 输入1‘or ’1‘ = ’1 也可以登陆成功 cmd.parameters.Add(new SqlParameters("UN",username)); cmd.parameters.Add(new SqlParameters("P",username)); int i=Convert.ToInt32(cmd.ExecuteScalar()); if(i>0) {Console.WriteLine("登陆成功!"); } else {Console.WriteLine("登陆失败!");}
Prarmeters类型转换的一个BUG
它传参数0的时候它就会自动默认为调用 类型的一个重载,要想给里边传常量,就得将其转换为object类型
cmd.parameters.Add(new SqlParameters("UN",(object)0));
数据库的查询、更新
可以将此代码跟数据库连接方法一的代码放在一个类文件中,方便调用,修改,当然,需要重复写的代码都可以放在单独一个文件中方便调用
/// <summary> /// 执行修改sql语句,如insert\update\delete /// </summary> /// <param name="sql"></param> /// <returns></returns> public static int ExecuteModi(string sql) { using (SqlConnection conn = GetConn()) { SqlCommand cmd = new SqlCommand();//创建执行命令的对象 cmd.Connection = conn;//指定数据库连接 cmd.CommandText = sql;//指定要执行的sql语句 try { return cmd.ExecuteNonQuery();//执行, 并返回受影响的行数 } catch { return -2; } } }
配置文件
如果一个程序中多处会用到数据库连接字符串,则可以将连接数据库字符串写在一个应用程序配置文件中,方便修改
方法:在项目中添加一个应用程序配置文件
然后给里边添加
<connectionStrings>
<add name="自己取个名字" connectionString="连接字符串">
</connectionStrings>
要用到这个配置文件,则需要在项目引用里边添加System.Configuration ,然后再项目中引用using System.Configuration指令就可以用了
引用方法:
ConfigurationManager.ConnectionStrings["配置文件中自己取的名字"].ConnectionString 得到字符串
DataSet数据集(返回DataTable类型的查询数据的集合)
DataSet非为弱类型DataSet和强类型DataSet
DataSet和DataReader的区别
DataReader是直接从数据库取数据的,所以,出了using范围它就停止了(占用内存可以忽略不计)
而DataSet是从数据库中查出数据,饭后返回一个数据集,即使除了using范围,照样可以调用(缺点:查询结果占用内存,要查询数据量过大时它会把内存撑爆,所以,还是要用DataReader,DataSet只是在查询数据量小得时候使用)
DataSet用法代码
public static DataTable OpenQuery(string sql) { using (SqlConnection conn = GetConn()) { SqlDataAdapter sda = new SqlDataAdapter(sql, conn); DataSet ds = new DataSet(); sda.Fill(ds); return ds.Tables[0]; } }
调用:
DataTable dt = OpenQuery(" select * from table"); //DataSet返回值为DataTable类型的,所以,需要定义一个DataTable类型的变量来接受返回值 for(int i=0;i<dt.Rows.Count;i++) { DataRow row = dt.Rows[i];//返回每一行 string name=Convert.ToString(row["列名"]); MessageBox.Show(...); }
DataSet的更新
但是,DataSet是进行离线查询的,修改的数据只存在在内存中,要想修改到数据库中,就需要用到sda.Update(ds)方法更新数据(这只是修改到内存中),
然后需要创建新的Command,然后CommandText用更新语句将数据修改到数据库
或者使用SqlCommandBuilder 系统会自动为我们添加更新语句
public static DataTable OpenQuery(string sql) { using (SqlConnection conn = GetConn()) { SqlDataAdapter sda = new SqlDataAdapter(sql, conn); DataSet ds = new DataSet(); sda.Fill(ds);//DataSet更新数据 DataTable dt = ds.Tables[0];DataRow row = dt.Rows[0];row["Name"]="张三";table.Rows.RemoveAt(1); //移除制定行table.NewRow(); //新建行sda.InsertCommand = conn.CreateCommand();sda.InsertCommand.CommandText="insert into..." //自己写Command,比较麻烦//使用SqlCommandBuilder 系统会自动为我们添加更新语句SqlCommandBuilder builder = new SqlCommandBuilder(sda); //也可以直接new,不用实例new SqlCommandBuilder(sda); sda.Update(ds); } }
可空数据类型
如果数据库中有一个int 类型的字段可以为空类型,但是C#的int类型不能为空类型,所以,就需要声明一个可空类型的int
声明方法: 在int后加?
int? i=0;
int? j=null;
弱类型DataSet的缺点
只能通过列名引用,dataset.Tables[0].Rows[0]["Age"],如果写错了列名编译时不会发生错误,因此开发者必须要记着列名
int age=Convert.ToInt32(dataset.Rows[0]["Age"]),取到的字段的值都是object类型,必须小心翼翼的进行转换,不仅麻烦,而且容易出错
将Dataset传递给其他使用者,使用者很难识别出有哪些列可以供使用
运行时才知道所有的列名,数据绑定麻烦,无法使用winform,asp.net的快速开发功能
强类型DataSet(其实就是一种代码生成机制)
强类型使用的两种方法,一种是自己写,一种是利用系统自动为我们生成
自己写:
新建一个类,该类继承自DataRow,里边建立对应数据库各个字段的属性
public int proID { get { return Convert.ToInt32(this["proID"]); } set { this["proID"] = value; } } public string proName { get { return Convert.ToString(this["proName"]); } set { this["proName"] = value; }
另一种方法:调用VS自带函数
新建一个数据集文件 将需要创建的表拖到数据集设计图界面(数据集只是根据字段名生成一个强类型的DataSet,并没有将数据拖过来)
然后将文件名.数据集名引用进来
using 文件名.数据集名
然后添加代码:
//promaryTableAdapter为数据集名称 promaryTableAdapter adapter = new promaryTableAdapter(); //获得数据需要将数据集的全称引入,因为它们不再同一命名空间下 AdoCity.DataSet1.promaryDataTable data = adapter.GetData(); for (int i = 0; i < data.Count; i++) { //得到返回数据的某一行 AdoCity.DataSet1.promaryRow userRow = data[i]; MessageBox.Show(userRow.proID.ToString()); }
类型化DataSet的更新
调用adapter的Update(data)方法更新数据,使用强类型DataSet的时候一定要设置主键,系统会自动加上更新语句
如果没有主键,则无法修改
修改表之后要想在数据集里边更新 需要右键->配置->然后完成,配置文件就会更新
增加字段 右键->配置->查询生成器,然后勾选需要增加的字段。 删除也是一样 也可以自己写SQL语句
这也是强类型DataSet的弱点
如果字段名里边有NULL则需要判断字段名是否为空 调用T_PersonsRow的IsNameNull方法
if (p.IsNameNull())
{
MessageBox.Show("姓名为空");
}
else
{
MessageBox.Show(p.Name);
}
强类型DataSet中增加自己的SQL语句
在数据集中 右键->添加->Query 写好之后为自己的方法取个名字
调用自己的SQL语句,跟GetData相同,直接adapter.自己的SQL方法名字
DataSet批量操作
在需要导入大量数据的时候就需要手动将连接打开,导入完之后再进行关闭
adapter.Connection.Open();
for(int i=1;i<=3000;i++)
{
adapter.Insert(i.ToString(),i.ToString(),0);
}
adapter.Connection.Close();
就整理了这么多,可能里边有错误
---------------------- Windows Phone 7手机开发、.Net培训、期待与您交流! ----------------------
详细请查看:http://edu.csdn.net/heima/
- 黑马程序员_ADO.NET学习知识总结
- 黑马程序员_Ado.net学习总结
- 黑马程序员_ADO.NET学习
- 黑马程序员_ADO.NET
- 黑马程序员_ADO.NET学习笔记
- 黑马程序员_ADO.NET学习笔记
- 黑马程序员_ADO.NET数据库连接
- 黑马程序员_学习日记5_ADO.Net入门1
- 黑马程序员_学习日记6_ADO.Net入门2
- 黑马程序员_学习日记15_ADO.Net之DataSet
- 黑马程序员_ADO.Net 数据库访问技术
- 黑马程序员_ADO.NET连接数据库
- 黑马程序员_ADO.Net(ExecuteReader,Sql注入与参数添加,DataSet,总结DataSet与SqlDataReader )
- 【黑马.net程序员】学习ADO.net和SQL知识总结
- 黑马程序员_ADO.NET 一个简单的登录程序
- 黑马程序员_ADO.NET通过DataSet访问数据库
- 黑马程序员_ADO.NET通过DataReader快速访问数据库
- 黑马程序员_ADO.NET操作数据库的过程
- 23种设计模式二:创建型工厂方法模式
- R语言与回归分析几个假设的检验
- poj 3083 Children of the Candy Corn 深搜加广搜
- 23种设计模式三:创建型抽象工厂模式
- Linux下的画图软件(相当于windows下的photoshop)
- 黑马程序员_ADO.NET学习知识总结
- js原理性研究
- x86寄存器的一般功能
- Android近场通信---NFC基础(一)
- 职业规划
- 设计模式中类的关系
- map的实现数据结构——红黑树
- Android SystemProperties设置/取得系统属性的用法总结
- 依赖、关联、聚合和组合之间区别