一、ADO.NET的概念:.Net中用来向数据库提交执行SQL语句的一堆类
1、数据库账号问题:本机访问一般直接用“Windows验证”即可,但是一般项目中单独的数据库服务器,程序在另外一台电脑上连接SQLServer,就会要求输入密码,否则不安全
2、SQLServer验证的两种方式:
1)Windows身份验证:本机连接或者受限的局域网连接(一般忘记管理员密码或者做系统配置的情况下使用)
2)sa用户:SQLServer的最高权限管理账户,启用方法:数据库根节点--->安全性--->sa--->常规 --->修改密码。默认强制复杂密码,可以取消
基于安全考虑,生产环境时,不要用sa账户,而是针对数据库建立专用的受限账户
ASP.NET、WinForm、WPF等连接操作数据库的技术都是用的ADO.NET
二、连接数据库(数据库验证)
Windows验证:Data Source=.;Database=test;Integrated Security=True
SQL验证: Data Source=.;Database=test;Integrated Security=True
连接数据库:
string str = @"Data Source=.;Initial Catalog=MyTest;Persist Security Info=True;User ID=sa;Password=123"; //数据库验证字符串
using(SqlConnection conn = new SqlConnection(str))
{
conn.Open();
//数据库操作 }
连接字符串:Data Source=.;Initial Catalog=MyTest;Persist Security Info=True;User ID=sa;Password=123
Data Source:数据源,服务器,.或者127.0.0.1表示本机的SQLServer,如果是连接其他计算机的数据库,则填写服务器的ip地址
Initial Catalog:数据库名称
Persist Security Info:安全防护
User ID:数据库连接账号
Password:数据库连接密码
ADO.NET中通过SqlConnetion类来创建到SQLServer的连接对象,一个对象代表一个数据库连接,因为连接类SqlConnetion等资源实现了IDisposable接口,
所以可以用using来进行资源管理,而不用手动释放资源
三、数据库操作
数据库连接完成后,可以进行数据库操作了。
1、调用数据库连接对象的CreateCommand方法,创建一个数据库命令类SqlCommand的对象.
SqlCommand cmd = conn.CreateCommand()
2、设置cmd的CommandText属性,写入要操作的SQL语句
cmd.CommandText = "Insert into T_Student(Name,Age) values('xxx',40)";
3、调用cmd的方法,执行数据库操作
因为命令类:SqlCommand也实现了接口IDisposable,所以也可以写在using中,完整代码如下:
using(SqlConnection conn = new SqlConnection(str))
{
conn.Open();
//数据库操作
//调用连接对象conn的CreateCommand方法,创建一个向数据库发命令(Command)类的对象,调用此对象的属性和方法完成数据库操作
using (SqlCommand cmd = conn.CreateCommand())
{
//命令类对象的属性:CommandText,是设置要执行的SQL语句
cmd.CommandText = "Insert into T_Student(Name,Age) values('xxx',40)";
//调用方法:ExecuteNonQuery,是执行SQL语句,并返回受影响的行数,返回值int类型
cmd.ExecuteNonQuery();
}
}
命令对象的SQL语句执行方法:
1)ExecuteNonQuery:一般用在执行非查询SQL语句,删、改、插,返回受影响的行数int
2)ExecuteScalar: 一般用在执行只有一行一列返回值的查询语句(select),返回第一行第一列的内容,返回值object类型
3)ExecuteReader:一般用在执行有多行查询结果的SQL语句,返回一个SqlDataReader对象,注意:查询结果放在数据库中,没有在程序中
SqlDataReader对象reader,调用read()方法,逐条读取查询结果,返回值是bool类型,如果还没读取完,返回true
读取数据完整代码:
using(SqlConnection conn = new SqlConnection(str))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select * from T_Student";
//SqlDataReader也有IDisposable接口,所以可写在using中
using(SqlDataReader reader = cmd.ExecuteReader())
{
//每调用一次Read(),指针往后移一位,直到数据读取完毕,返回false
while(reader.Read())
{
string name = reader.GetString(1); //读取第1列的值
MessageBox.Show(name);
}
}
}
}
reader的get方法,参数int n为读取查询数据的第n列,返回值以第n列的值类型而定
四、参数化查询:避免SQL注入漏洞攻击
当用控件内容加入SQL执行语句时:
cmd.CommandText = @"select Age from T_Student where Name='"+
txtName.Text.Trim()+"'";
如果控件内容是: 1' or '1'='1
SQL就变成了:
cmd.CommandText = @"select Age from T_Student where Name='1' or '1'='1'
因为’1‘ =’1‘ 是一直成立的,这样条件过滤器一直未true,执行的结果是数据库中所有数据。
比如某个用户想查询自己的用户名和密码,结构通过注入漏洞,就可以查询到所有人的账户密码。这是很危险的
所以在给SQL传参数时不能用拼字符串的方式。要用“查询参数”来将参数传入SQL语句!
参数化查询:
1、在SQL语句中挖一个坑:@+坑的名字
cmd.CommandText = @"select Age from T_Student where Name<strong>=@name</strong>";
2、通过数据库连接对象的命令对象的只读属性Parameters给坑传参。
第一种方法:
cmd.Parameters.AddWithValue("@name", txtName.Text);
第二种方法:比较符合编程理念
cmd.Parameters.Add(new SqlParameter("@Name", txtName.Text));
参数化查询可以传多个参数:
cmd.CommandText = @"select Age from T_Student where Name=@name and Age>@age";
//cmd.Parameters.AddWithValue("@name", txtName.Text);
cmd.Parameters.Add(new SqlParameter("@name", txtName.Text));
cmd.Parameters.Add(new SqlParameter("@age", txtAge.Text));
参数化 传参不止用在查询语句,还可以用在插入语句、删除语句、修改语句
插入语句:insert into .....values(“@name”,“@age”)
删除语句:delete .....where Name=@name orAge=@age
修改语句:update T_Student set Age=@myAge