黑马程序员 C#学习笔记③ ADO.NET实现登录案例
2014-03-07 12:37
771 查看
----------------------
ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------简单的登录案例
使用ADO.Net技术来进行对数据库的交互来得到数据, 再进行判断完成登录程序.
应用技术: 编写SqlHelper类, sql语句, 在App.Config中设置连接字符串.
(1) App.config的设置
(2) SqlHelper类
在SqlHelper类中, 用函数的方式实现ExcuteNonQuery和DataSet
其中使用的知识有:
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 类型 表示用户登录失败的次数
通过主窗口的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指针.
直接在函数中完成了所有判断, 也可以设置一个User类, 与数据库中一样的结构, 然后将函数类型声明成User, 在函数内赋值, 最后返回, 在函数外判断.
主要是基础知识运用, 所以这样也可以.
(3) MainWindow.xaml.cs
这个和第一个案例一样, 只是没有判断了.
----------------------
ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------详细请查看:www.itheima.com
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
相关文章推荐
- 黑马程序员之C#学习笔记:ADO.NET入门级材料
- 黑马程序员之ADO.NET学习笔记:不用第三个变量,实现两数交换
- 黑马程序员 C#学习笔记② ADO.NET技术步骤
- 黑马程序员之asp.net学习笔记:巧用C#做中间语言 实现java调用.net
- sql server 关于表中只增标识问题 C# 实现自动化打开和关闭可执行文件(或 关闭停止与系统交互的可执行文件) ajaxfileupload插件上传图片功能,用MVC和aspx做后台各写了一个案例 将小写阿拉伯数字转换成大写的汉字, C# WinForm 中英文实现, 国际化实现的简单方法 ASP.NET Core 2 学习笔记(六)ASP.NET Core 2 学习笔记(三)
- 黑马程序员之ADO.NET学习笔记:省市选择程序,数据全部来自于数据库。
- ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现
- 黑马程序员 C#学习笔记⑥ 三层架构基础实现员工信息管理
- 黑马程序员之ADO.NET学习笔记:通过数据集操作数据
- C#.NET学习笔记---C#中方法覆盖时override和new的比较,abstract和virtual的比较(含C#多态的实现)
- 黑马程序员—学习笔记之ADO.Net
- 黑马程序员之ADO.NET学习笔记:.NET中被大家容易忽视的问题
- ADO.NET学习系列(三)----做一个登录案例
- 【Java学习笔记】19.登录和注册案例(IO流实现)
- 黑马程序员之ADO.NET学习笔记:执行Insert操作
- 黑马程序员--学习笔记之ADO.Net基础知识
- C#回顾学习笔记三十八:ADO.NET的使用与总结
- C#学习笔记(六)-使用ADO .NET查询和操作数据库
- C#进阶ADO.NET基础三 案例:登录框、导入文档、省市联动
- 黑马程序员之ADO.NET学习笔记: SqlTransaction(事务)