黑马程序员—ADO.NET

---------------------- Windows Phone 7手机开发.NET培训、期待与您交流!----------------------

 

1.ADO.NET 连接SQLServer 
 ADO.NET 中提供了对各种不同数据库的统一操作接口。
 内嵌MDF文件:添加一个“基于服务的数据库”,生成一个MDF文件,在程序中通过连接字符串将这个MDF文件attach 到SQL Server,
 连接结束后自动分离。MDF文件随着项目走,用起来方便,和在数据库服务器上创建数据没什么区别,运行的是会自动附和(attach)。
 
 附加:SQL server 2008 中数据库/附加/选择MDF 文件
 分离
 用时,在控制台,WInForm项目中在Main函数最开始的位置加入以下代码: 

 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);
 }

 2.连接SQLServer 
 连接字符串:程序通过连接字符串制定要连哪台服务器上的、哪个势力的哪个数据库、用什么用户名和密码等。
 项目内嵌mdf文件形式的连接字符串:

 "Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True"

  ".\SQLEXPRSS"表示本机上的SQLEXPRSS实例,如果数据库实例名不是SQLEXPRESS,则需要修改,"Database1.mdf"为mdf的文件名。
 "Database1.mdf" 文件名
 
 ADO.NET 中通过SqlConnection 类创建到SQLServer的连接,SqlConnection代表一个数据库连接。
 ADO.NET 中的SqlConnection、SqlCommand、SqlDataReader以及FileStream连接等资源都实现了IDisposable 接口,可以使用using进行资源管理。
 当using的{}中的代码执行完了,就会自动关闭和释放对象所占用的资源。程序第一次连接数据库很耗时,因此对同一个数据库的连接不要重复连接,应该设为一个全局变量。
   

static void Main(string[] args)
         {
             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);
             }
 
             using (SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True"))
             { 
                 conn.Open();
                 using (SqlCommand cmd = conn.CreateCommand())
                 {
                     cmd.CommandText = "Insert into MyTable1(Name) values('abc')";
                     cmd.ExecuteNonQuery(); //执行一个非查询语句
                     Console.WriteLine("插入成功!");
                 }
             }
             Console.WriteLine("OK!");
             Console.ReadKey();
         }

3.用户登录判断  

class Program
     {
         static void Main(string[] args)
         {
             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);
             }
 
             Console.WriteLine("请输入用户名:");
             string username=Console.ReadLine();
             Console.WriteLine("请输入密码:");
             string password=Console.ReadLine();
             using (SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database2.mdf;Integrated Security=True;User Instance=True"))
             {
                 conn.Open();
                 using (SqlCommand cmd = conn.CreateCommand())
                 {
                     cmd.CommandText = "select * from T_Users where UserName='"+username+"'";
                     using (SqlDataReader  reader=cmd.ExecuteReader ())
                     {
                         if (reader.Read())
                         {
                             string dbpassword = reader.GetString(reader.GetOrdinal("Password"));
                             if (password == dbpassword)
                             {
                                 Console.WriteLine("登录成功!");
                             }
                             else
                             {
                                 Console.WriteLine("密码错误,登录失败!");
                             }
                         }
                         else
                         {
                             Console.WriteLine("用户名错误!");
                         }
                     }
                 }
             }
             Console.WriteLine("OK!");
             Console.ReadKey();
         }
     }

4.向表中插入数据 
 注意:
  cmd.CommandText = "Insert into T_Users(Username,Password) values ('" + username +"','" +password +"')";
  //cmd.CommandText = "Insert into T_Users(Username,Password) values(username,password)"; 单纯的添加字符串username和password
 
 注意,字符串的拼接;values后面值的单引号 ''
 User 是数据库中的关键字,在使用时,必须 [User]
 好习惯:表名T_开头,字段F开头
 
6.ExecuteScalar 
 SqlCommand 的ExecuteScalar方法用于执行查询,并返回查询所返回的结果集中第一行的第一列,因为不能确定返回值的类型,所以返回值是object类型。
 ExecuteScalar一般用于执行,查询表里有多少条数据,或者取表中的最大值。
 ExecuteScalar 应用(查询自动生成的主键的值):
 
  cmd.CommandText = "Insert into T_Users(UserName,Password) output inserted.id values('admin','888888')";
  //得到自增字段的值
  int id = Convert.ToInt32(cmd.ExecuteScalar());
  Console.WriteLine("新插入的主键:{0}",id);
 
7.执行查询 
 执行有多行结果集的用ExecuteReader  

using (SqlCommand cmd = conn.CreateCommand())
  {
      cmd.CommandText = "select * from T_Users";
      using (SqlDataReader reader = cmd.ExecuteReader())
     {
        while (reader.Read())  //每调用一次Read(),就往下读一行数据,当没数据时,返回false
        {
           Console.WriteLine(reader.GetString(1));
        }
     }
  }

 reader.GetString 只能得到某一列的值,只能传序号
 reader的GetString,GetInt32 等方法只接受整数参数,也就是序号,用GetOrdinal方法根据列名动态得到序号。
 例如 :Console.WriteLine(reader.GetString (reader.GetOrdinal("UserName")));
 
 reader.GetOrdinal("UserName") //得到列的序号
 reader.GetString (reader.GetOrdinal("UserName"))  //根据序号,得到列名
 
 读取多列的值:  

using (SqlDataReader reader = cmd.ExecuteReader())
  {
     while (reader.Read())  //每调用一次Read(),就往下读一行数据,当没数据时,返回false
     {
       //Console.WriteLine(reader.GetString(1));
       string username=reader.GetString (reader.GetOrdinal("UserName"));
       int id = reader.GetInt32(reader.GetOrdinal("Id"));
       string password = reader.GetString(reader.GetOrdinal("Password"));
       Console.WriteLine("Id={0},Username={1},Password={2}",id,username,password );
     }
 }


 为什么用using:
  conn.Close 之后,还可以再open; conn.Dispose 之后不可以再open。
  using在出了作用域以后调用Dispose,SqlConnection,FileStream等的Dispose内部都会做这样的判断:
 (判断有没有close,如果没有close就先close,再Dispose。)
 
 and 方法登录判断:  

  using (SqlCommand cmd = conn.CreateCommand())
  {
    cmd.CommandText = "select count(*) from T_Users where UserName='"+username +"' and Password='"+password+ "'";
    int i = Convert.ToInt32(cmd.ExecuteScalar());
    if (i > 0)
    {
       Console.WriteLine("登录成功!");
    }
    else
    {
       Console.WriteLine("登录失败!");
    }
   }

 当输入密码为:1' or '1'='1 也可以提示登录成功,造成SQL注入漏洞攻击
 最佳实现方法:  

  using (SqlCommand cmd = conn.CreateCommand())
  {
    //占位符的形式,可以理解为拿着输入的内容与原有用户名和密码比较
    cmd.CommandText = "select count(*) from T_Users where UserName=@UN and Password=@P";
    cmd.Parameters.Add(new SqlParameter ("UN",username ));
    cmd.Parameters.Add(new SqlParameter ("P",password ));
 
    int i = Convert.ToInt32(cmd.ExecuteScalar());
    if (i > 0)
    {
       Console.WriteLine("登录成功!");
    }
    else
    {
       Console.WriteLine("登录失败!");
    }
  }


8.登录练习1 
 用户界面中进行登录判断,输错三次禁止登陆,用数据库记录ErrorTimes. 

namespace 登录练习1
 {
     public partial class Form1 : Form
     {
         public Form1()
         {
             InitializeComponent();
         }
 
         private void IncErrorTimes()
         {
             using (SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\MyDB.mdf;Integrated Security=True;User Instance=True"))
             {
                 conn.Open();
                 using (SqlCommand updateCmd = conn.CreateCommand())
                 {
                     updateCmd.CommandText = "update T_Users set ErrorTimes=ErrorTimes+1 whereUserName=@UN ";
                     updateCmd.Parameters.Add(new SqlParameter("UN", txtUserName.Text));
                     updateCmd.ExecuteNonQuery();
                 }
             }
         }
 
         private void ResetErrorTimes()
         {
             using (SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\MyDB.mdf;Integrated Security=True;User Instance=True"))
             {
                 conn.Open();
                 using (SqlCommand updateCmd = conn.CreateCommand())
                 {
                     updateCmd.CommandText = "update T_Users set ErrorTimes=0 whereUserName=@UN ";
                     updateCmd.Parameters.Add(new SqlParameter("UN", txtUserName.Text));
                     updateCmd.ExecuteNonQuery();
                 }
             }
         }
 
         private void txtLogin_Click(object sender, EventArgs e)
         {
             using (SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\MyDB.mdf;Integrated Security=True;User Instance=True"))
             {
                 conn.Open();
                 using (SqlCommand cmd = conn.CreateCommand())
                 {
                     cmd.CommandText = "select * from T_Users where UserName=@UN";
                     cmd.Parameters.Add( new  SqlParameter  ("UN",txtUserName.Text));
                     using (SqlDataReader reader= cmd.ExecuteReader())
                     {
                         if (reader.Read())
                         {
                             int errorTimes = reader.GetInt32(reader.GetOrdinal ("ErrorTimes"));
                             if (errorTimes > 3)
                             {
                                 MessageBox.Show("登陆错误次数过多,禁止登录!");
                                 return;
                             }
                             string dbpassword = reader.GetString(reader.GetOrdinal ("Password"));
                             if (dbpassword == txtPassword.Text)
                             {
                                 MessageBox.Show("登陆成功!");
                                 ResetErrorTimes();
                             }
                             else
                             {
                                 IncErrorTimes();
                                 MessageBox.Show("登录失败!");
                             }
                         }
                         else
                         {
                             MessageBox.Show("用户名不存在!");
                         }
                     }
                 }
             }
         }
     }
 }


9.文件的导入导出 
 数据导入:从文本文件导入用户信息        

          if (ofdImport.ShowDialog() != DialogResult.OK)
            {
                return;
            }
            using (FileStream fileStream = File.OpenRead(ofdImport.FileName))
            {
                using (StreamReader streamReader = new StreamReader(fileStream))
                {
                    using (SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True"))
                    //创建连接时非常耗时的,因此不要每次操作都创建连接
                    {
                        conn.Open();
                        using (SqlCommand cmd = conn.CreateCommand())
                        {
                            cmd.CommandText = "Insert into T_Persons(Name,Age) values(@Name,@Age)";
                            string line = null;
                            while ((line = streamReader.ReadLine()) != null)
                            {
                                string[] strs = line.Split('|');
                                string name = strs[0];
                                int age = Convert.ToInt32(strs[1]);
                                cmd.Parameters.Clear(); //参数不能重复添加,在while中一直用的就是一个SqlCommand对象

                                cmd.Parameters.Add(new SqlParameter("Name", name));
                                cmd.Parameters.Add(new SqlParameter("Age", age));
                                cmd.ExecuteNonQuery();
                            }
                        }
                    }
                }
            }
            MessageBox.Show("导入成功!");


 

---------------------- Windows Phone 7手机开发.NET培训、期待与您交流!----------------------

详细请查看:http://edu.csdn.net/heima/


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值