您的位置:首页 > 职场人生

黑马程序员 C#学习笔记③ ADO.NET实现登录案例

2014-03-07 12:37 771 查看
----------------------
ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------简单的登录案例

使用ADO.Net技术来进行对数据库的交互来得到数据, 再进行判断完成登录程序.

应用技术: 编写SqlHelper类, sql语句, 在App.Config中设置连接字符串.

(1) App.config的设置

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="dbConnStr" connectionString="Data Source=.;Initial Catalog=MyTest;User ID=sa;Password=123456"/>
</connectionStrings>
</configuration>


(2) SqlHelper类

在SqlHelper类中, 用函数的方式实现ExcuteNonQuery和DataSet

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Data.SqlClient;
using System.Data;

namespace 登录案例2
{
static public class SqlHelper
{
static string connStr = ConfigurationManager.ConnectionStrings["dbconnStr"].ConnectionString;

//实现一个ExcuteNonQuery和DataSet

public static int ExcuteNonQuery(string sql, params SqlParameter[] sqlParameters)
{
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.Parameters.AddRange(sqlParameters);
cmd.CommandText = sql;
return cmd.ExecuteNonQuery();
}
}
}

public static DataTable ExecuteDataSet(string sql, params SqlParameter[] sqlParameters)
{

using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.Parameters.AddRange(sqlParameters);
cmd.CommandText = sql;
DataSet dataset = new DataSet();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(dataset);
return dataset.Tables[0];
}
}
}
}
}


其中使用的知识有:

using() 实现了IDisposable接口的类, 就可以使用using, 这样可以自动释放资源

参数数组 params 可以给函数传递不定个数的参数, 并且可以简化传递方式.

声明包含参数数组的函数

//该函数返回不定个数的整数的总和

public int Sum(params int[] integers)

{

int sum=0;

foreach(int integer in integers)

{

sum += integer;

}

return sum;

}

调用方式

int result = Sum(1,2,3,4,5);

(3) 通过调用SqlHelper的函数得到返回值, 然后进一步在MainWindow.xaml.cs中进行处理

MyTest数据库中的表T_User

Id UserName Password ErrorTimes

1 LM 123456 0

Id 主键 bigint类型

UserName nvarchar(50)类型 表示用户名

Password nvarchar(50)类型 表示密码

ErrorTimes int 类型 表示用户登录失败的次数

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Data;
using System.Data.SqlClient;

namespace 登录案例2
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private void btnLogIn_Click(object sender, RoutedEventArgs e)
{
//先判断控件中输入数据的有效性
if (txtUserName.Text.Trim().Length<=0)
{
MessageBox.Show("需要输入用户名");
return;
}
if (pwdBox.Password.Length<=0)
{
MessageBox.Show("需要输入密码");
return;
}
DataTable datatable = SqlHelper.ExecuteDataSet("select * from T_User where UserName=@Name",
new SqlParameter("@Name", txtUserName.Text));
DataRowCollection rows = datatable.Rows;
if (rows.Count<=0)
{
//rows集合中没有数据, 即查询结果为空
MessageBox.Show("用户不存在!");
return;
}
else if (rows.Count>1)	//防御性编程, 考虑到所有情况
{
throw new Exception("用户名重复!");
}
else
{
//返回了查询结果
DataRow row = rows[0];
if ((int)row["ErrorTimes"]>=3)	//先查看用户的登录错误次数
{
MessageBox.Show("输入错误次数过多,请半小时后登录");
return;
}
else if ((string)row["Password"]==pwdBox.Password)
{
//密码正确
MessageBox.Show("登录成功!");
return;
}
else
{
//密码不正确, 再向数据库中写数据, 将ErrorTimes+1
MessageBox.Show("用户名或密码不正确!");
SqlHelper.ExcuteNonQuery("Update T_User set ErrorTimes=ErrorTimes+1 where ID=@ID",
new SqlParameter("@ID", row["ID"].ToString()));
}
}
}
}
}


通过主窗口的txtUserName(TextBox类型)控件的Text属性得到用户名, pwdBox(PasswordBox)控件的Password属性得到密码

使用sql查询语句: select * from T_User where UserName='LM' (在程序中是用传参完成的) , 这样会得到一个表, 在程序中使用的DataSet, 会得到一个

DataTable类型的集合, 一般只是执行一次查询操作, 因此只返回一个表. 再通过一系列的属性转换来判断与用户输入的用户名或者密码是否相符来完成程序.

可以看出DataSet对于小数据的查询是很方便操作的. 下面使用SqlDataReader来完成案例

(1) App.config的设置是一样的.

(2) SqlHelper类

因为使用的查询类型不同, 自然得重新编写. 这里就体现出了DataSet和SqlDataReader的不同, 因为DataSet是将结果存储在本地, 而SqlDataReader是将结果

存储在服务器端, 然后返回一个reader指针.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Data.SqlClient;
using System.Windows;

namespace 登录案例
{
class SqlHelper
{
private static string connStr = ConfigurationManager.ConnectionStrings["dbConnStr"].ConnectionString;

public static void ExecuteRead(string str,string password, params SqlParameter[] sqlParameters)
{
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.Parameters.AddRange(sqlParameters);
cmd.CommandText = str;

string userName="";
foreach (SqlParameter sp in sqlParameters)
{
userName = sp.Value.ToString();
}
SqlDataReader reader = cmd.ExecuteReader();
if (!reader.HasRows)                        //reader中没有行存在, 意即没有返回结果
{
MessageBox.Show("用户名不存在!");
return;
}
else
{
//特别注意的是reader指针是在第一行的前面, 而Read()只是移动到下一行, 并返回是不是空.
reader.Read();

//首先判断ErrorTimes次数是否大于等于3,使用reader["ErrorTimes"]也行,但是返回的是object,需要类型转换(int).
if (reader.GetInt32(3) >= 3)     //(int)reader["ErrorTimes"]
{
MessageBox.Show("输入错误次数过多, 半小时内不能登录!");
}
else if (reader.GetString(2) == password)
{
MessageBox.Show("登录成功");
}
else
{
//密码错误, ErrorTimes+1
MessageBox.Show("用户名或者密码错误!");
//在再次向数据库中写数据前, 得先关闭reader, 不然会报错
reader.Close();
using (SqlCommand cmd2 = conn.CreateCommand())
{
cmd2.CommandText = "Update T_User set ErrorTimes=ErrorTimes+1 where UserName=@Name";
cmd2.Parameters.Add("@Name", userName); //因为@Name已经声明, 在同一查询批次中需唯一
cmd2.ExecuteNonQuery();
}
}
}
}
}
}
}
}


直接在函数中完成了所有判断, 也可以设置一个User类, 与数据库中一样的结构, 然后将函数类型声明成User, 在函数内赋值, 最后返回, 在函数外判断.

主要是基础知识运用, 所以这样也可以.

(3) MainWindow.xaml.cs

这个和第一个案例一样, 只是没有判断了.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data.SqlClient;

namespace 登录案例
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private void btnLogIn_Click(object sender, RoutedEventArgs e)
{
SqlHelper.ExecuteRead("select * from T_User where UserName=@Name",txtPassword.Text,
new SqlParameter("@Name", txtUserName.Text));

}
}
}


----------------------
ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------详细请查看:www.itheima.com
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐