本文将介绍利用C#和MySQL实现注册登录,该功能是后续世界聊天室项目的前置功能。
目录
数据库设计
程序设计
数据库设计
实现步骤
step1 在原有项目中新建数据库
step2 新建基于服务的数据库
step3 添加新表
step4 数据库设计
step5 修改表名
按照步骤step1至step5操作最终结果如下图所示:
注:
1.表名默认为Table,后续程序设计中的SQL语句中的表应为[Table],同理step5修改表名为User,后续程序设计中的SQL语句中的表为[User];
2.IsOnline的数据类型为nchar,默认值为0表示不在线,1表示用户在线,用户在线时无法登陆。
程序设计
1.程序框架
Login窗体负责注册登录,Client窗体为世界聊天室,UsersDataBase负责存储注册的用户信息。
2.窗体设计
可输入账号密码,点击按键即可注册、登录和重置。
3.控件选择
根据窗体设计选择相应的控件,包含按键、以及标签等。
4.程序设计
step1 连接数据库
获取连接数据库的连接字符串,同时数据库的连接要保持晚开早关,保证数据库安全。
static string connStr = @"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=D:\Code\TCP\Server\UsersDataBase.mdf;Integrated Security=True"; //连接数据库标识
using (SqlConnection conn = new SqlConnection(connStr)) //创建数据库连接类
{
conn.Open(); //打开数据库连接
/* 执行内容 */
conn.Close(); //关闭数据库连接
}
step2 点击注册按键时,将用户账号密码写入数据库中
/* 当时点击注册按键时运行 */
private void btnSign_Click(object sender, EventArgs e)
{
/* 获取控件里的值 */
string name = nameTextBox.Text;
string password = passwordTextBox.Text;
if (name == "" || password == "")
{
MessageBox.Show("请输入完整");
cleanText(); //清空文本
return;
}
try
{
string sqlSelect = string.Format("select count(*) from [User] where Name='{0}'", name); //SQL语句,选择表User中Name为name的行
/// 创建对象时使用using可以在使用完该对象后,自动释放资源
using (SqlConnection conn = new SqlConnection(connStr)) //创建数据库连接类
{
using (SqlCommand cmdSelect = new SqlCommand(sqlSelect, conn)) //创建数据库命令类
{
conn.Open(); //打开数据库连接
if ((int)cmdSelect.ExecuteScalar() > 0 || name == "admin")
{
conn.Close(); //关闭数据库连接
MessageBox.Show("用户已存在!");
cleanText(); //清空文本
}
else
{
string sqlInsert = string.Format("insert into [User] (Name,Password,IsOnline)values('{0}','{1}','{2}')", name, password, 0); //SQL语句,
//SQL语句,将参数Name、Password、IsOnline插入到表User中
SqlCommand cmdInsert = new SqlCommand(sqlInsert, conn);
cmdInsert.ExecuteNonQuery(); //执行SQL语句
conn.Close(); //关闭数据库连接
MessageBox.Show("注册成功");
cleanText(); //清空文本
}
}
}
}
catch (Exception ex) //异常捕获
{
MessageBox.Show(ex.ToString()); //显示异常信息
}
}
注:
1.输入的账号密码应非空,ClenText为自定义函数,用于清空TextBox控件中的文本;
2.利用关键字using可以降低内存的消耗,在使用完对象后内存会被回收;
3.数据库连接的打开与关闭要晚开早关,用的时候才打开,一用完就关掉是最安全的;
4.账号不得重复注册,若账号已存在会注册失败。
step3 点击登陆按键时,输入的密码与账号密码进行匹配
/* 当点击登录按键时运行 */
private void btnLoad_Click(object sender, EventArgs e)
{
/* 获取控件里的值 */
string name = nameTextBox.Text;
string password = passwordTextBox.Text;
if (name == "" || password == "")
{
MessageBox.Show("请输入完整!");
cleanText(); //清空文本
return;
}
if (name == "admin")
{
MessageBox.Show("管理员账号!请重新输入");
cleanText(); //清空文本
return;
}
string sqlSelect = string.Format("select Password,IsOnline from [User] where Name='{0}'", name); //SQL语句,选择passWord和isOnline
/* 创建对象时使用using可以在使用完该对象后,自动释放资源 */
using (SqlConnection conn = new SqlConnection(connStr)) //创建数据库连接类
{
using (SqlCommand cmdSelect = new SqlCommand(sqlSelect, conn)) //创建数据库命令类
{
conn.Open(); //打开数据库连接
SqlDataReader sqlRead = cmdSelect.ExecuteReader(); //遍历数据库
//cmdSelect.ExecuteScalar(); //执行SQL语句
if (!sqlRead.Read())
{
conn.Close(); //关闭数据库连接
MessageBox.Show("账号不存在!请重新输入");
cleanText(); //清空文本
}
else if (sqlRead["IsOnline"].ToString().Trim() == "1")
{
conn.Close(); //关闭数据库连接
MessageBox.Show("账号已登录!请重新输入");
cleanText(); //清空文本
}
else if (sqlRead["Password"].ToString().Trim() == password)
{
conn.Close(); //关闭数据库连接
MessageBox.Show("登录成功!");
string sqlUpdate = string.Format("update [User] set IsOnline='{0}' where Name='{1}'", 1, name); //SQL语句,更新isOnline为上线状态
using (SqlCommand cmdUpdate = new SqlCommand(sqlUpdate, conn)) //创建数据库命令类
{
conn.Open(); //打开数据库连接
//执行非查询命令时使用ExecuteNonQuery,会返回影响的行数
cmdUpdate.ExecuteNonQuery(); //执行SQL语句
conn.Close(); //关闭数据库连接
cleanText(); //清空文本
this.Hide(); //隐藏当前窗体
ClientForm clientForm = new ClientForm(name); //创建并初始化客户端窗体实例
clientForm.ShowDialog(); //显示客户端窗体
}
}
else
{
conn.Close(); //关闭数据库连接
MessageBox.Show("密码错误!请重新输入");
cleanText();
}
}
}
}
注:
1.输入的账号密码应非空,ClenText为自定义函数,用于清空TextBox控件中的文本;
2.利用关键字using可以降低内存的消耗,在使用完对象后内存会被回收;
3.数据库连接的打开与关闭要晚开早关,用的时候才打开,一用完就关掉是最安全的;
4.利用sqlSelect选择的行列均应该包含在语句中,例如Password用于判断密码是否匹配,IsOnline用于判断用户是否已上线;
5.点击登录按键后,只能隐藏该窗体,不能关闭该窗体,显示的窗体是子窗体,该窗体为主窗体,若关闭主窗体,所有窗口都会被关闭;
step4 输入管理员账号密码,点击重置按键时,将数据库内容清空
/* 当点击重置按键时运行 */
private void btnClean_Click(object sender, EventArgs e)
{
/* 获取控件里的值 */
string name = nameTextBox.Text;
string password = passwordTextBox.Text;
if (name == "" || password == "")
{
MessageBox.Show("请输入管理员账号密码!");
cleanText(); //清空文本
return;
}
else if (name == "admin" && password == "admin")
{
string sqlDelete = "delete from [User]"; //SQL语句,清空User内容
using (SqlConnection conn = new SqlConnection(connStr)) //创建数据库连接类
{
using (SqlCommand cmdDelete = new SqlCommand(sqlDelete, conn)) //创建数据库命令类
{
conn.Open(); //打开数据库连接
//执行非查询命令时使用ExecuteNonQuery,会返回影响的行数
cmdDelete.ExecuteNonQuery(); //执行SQL语句
conn.Close(); //关闭数据库连接
MessageBox.Show("重置成功!");
cleanText(); //清空文本
}
}
}
else
{
MessageBox.Show("管理员账号错误!");
cleanText(); //清空文本
}
}
注:
1.输入的账号密码应非空,ClenText为自定义函数,用于清空TextBox控件中的文本;
2.利用关键字using可以降低内存的消耗,在使用完对象后内存会被回收;
3.数据库连接的打开与关闭要晚开早关,用的时候才打开,一用完就关掉是最安全的;
4.利用sqlDelete清空数据库内容。
按照step1-step4完成程序设计,源码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Client
{
public partial class LoginForm : Form
{
/* 定义变量 */
static string connStr = @"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=D:\Code\TCP\Server\UsersDataBase.mdf;Integrated Security=True"; //连接数据库标识
public LoginForm()
{
InitializeComponent();
}
/* 当打开窗体时运行 */
private void LoginForm_Load(object sender, EventArgs e)
{
//Control.CheckForIllegalCrossThreadCalls = false; //取消对跨线程访问的检查
}
/* 当时点击注册按键时运行 */
private void btnSign_Click(object sender, EventArgs e)
{
/* 获取控件里的值 */
string name = nameTextBox.Text;
string password = passwordTextBox.Text;
if (name == "" || password == "")
{
MessageBox.Show("请输入完整");
cleanText(); //清空文本
return;
}
try
{
string sqlSelect = string.Format("select count(*) from [User] where Name='{0}'", name); //SQL语句,选择表User中Name为name的行
/// 创建对象时使用using可以在使用完该对象后,自动释放资源
using (SqlConnection conn = new SqlConnection(connStr)) //创建数据库连接类
{
using (SqlCommand cmdSelect = new SqlCommand(sqlSelect, conn)) //创建数据库命令类
{
conn.Open(); //打开数据库连接
if ((int)cmdSelect.ExecuteScalar() > 0 || name == "admin")
{
conn.Close(); //关闭数据库连接
MessageBox.Show("用户已存在!");
cleanText(); //清空文本
}
else
{
string sqlInsert = string.Format("insert into [User] (Name,Password,IsOnline)values('{0}','{1}','{2}')", name, password, 0); //SQL语句,
//SQL语句,将参数Name、Password、IsOnline插入到表User中
SqlCommand cmdInsert = new SqlCommand(sqlInsert, conn);
cmdInsert.ExecuteNonQuery(); //执行SQL语句
conn.Close(); //关闭数据库连接
MessageBox.Show("注册成功");
cleanText(); //清空文本
}
}
}
}
catch (Exception ex) //异常捕获
{
MessageBox.Show(ex.ToString()); //显示异常信息
}
}
/* 当点击登录按键时运行 */
private void btnLoad_Click(object sender, EventArgs e)
{
/* 获取控件里的值 */
string name = nameTextBox.Text;
string password = passwordTextBox.Text;
if (name == "" || password == "")
{
MessageBox.Show("请输入完整!");
cleanText(); //清空文本
return;
}
if (name == "admin")
{
MessageBox.Show("管理员账号!请重新输入");
cleanText(); //清空文本
return;
}
string sqlSelect = string.Format("select Password,IsOnline from [User] where Name='{0}'", name); //SQL语句,选择passWord和isOnline
/* 创建对象时使用using可以在使用完该对象后,自动释放资源 */
using (SqlConnection conn = new SqlConnection(connStr)) //创建数据库连接类
{
using (SqlCommand cmdSelect = new SqlCommand(sqlSelect, conn)) //创建数据库命令类
{
conn.Open(); //打开数据库连接
SqlDataReader sqlRead = cmdSelect.ExecuteReader(); //遍历数据库
//cmdSelect.ExecuteScalar(); //执行SQL语句
if (!sqlRead.Read())
{
conn.Close(); //关闭数据库连接
MessageBox.Show("账号不存在!请重新输入");
cleanText(); //清空文本
}
else if (sqlRead["IsOnline"].ToString().Trim() == "1")
{
conn.Close(); //关闭数据库连接
MessageBox.Show("账号已登录!请重新输入");
cleanText(); //清空文本
}
else if (sqlRead["Password"].ToString().Trim() == password)
{
conn.Close(); //关闭数据库连接
MessageBox.Show("登录成功!");
string sqlUpdate = string.Format("update [User] set IsOnline='{0}' where Name='{1}'", 1, name); //SQL语句,更新isOnline为上线状态
using (SqlCommand cmdUpdate = new SqlCommand(sqlUpdate, conn)) //创建数据库命令类
{
conn.Open(); //打开数据库连接
//执行非查询命令时使用ExecuteNonQuery,会返回影响的行数
cmdUpdate.ExecuteNonQuery(); //执行SQL语句
conn.Close(); //关闭数据库连接
cleanText(); //清空文本
this.Hide(); //隐藏当前窗体
ClientForm clientForm = new ClientForm(name); //创建并初始化客户端窗体实例
clientForm.ShowDialog(); //显示客户端窗体
}
}
else
{
conn.Close(); //关闭数据库连接
MessageBox.Show("密码错误!请重新输入");
cleanText();
}
}
}
}
/* 清空控件内容 */
private void cleanText()
{
nameTextBox.Text = "";
passwordTextBox.Text = "";
}
/* 当点击重置按键时运行 */
private void btnClean_Click(object sender, EventArgs e)
{
/* 获取控件里的值 */
string name = nameTextBox.Text;
string password = passwordTextBox.Text;
if (name == "" || password == "")
{
MessageBox.Show("请输入管理员账号密码!");
cleanText();
return;
}
else if (name == "admin" && password == "admin")
{
string sqlDelete = "delete from [User]"; //SQL语句,清空User内容
using (SqlConnection conn = new SqlConnection(connStr)) //创建数据库连接类
{
using (SqlCommand cmdDelete = new SqlCommand(sqlDelete, conn)) //创建数据库命令类
{
conn.Open(); //打开数据库连接
//执行非查询命令时使用ExecuteNonQuery,会返回影响的行数
cmdDelete.ExecuteNonQuery(); //执行SQL语句
conn.Close(); //关闭数据库连接
MessageBox.Show("重置成功!");
cleanText();
}
}
}
else
{
MessageBox.Show("管理员账号错误!");
cleanText();
}
}
}
}
最后,提供的源码打开了客户端窗体并把用户的账号通过窗口间传值的方式传递给客户端程序中,关闭客户端窗体时候,应该更新用户的在线状态,示例代码如下,读者可自行补充完成修改。
/* 当关闭窗体时运行 */
private void ClientForm_Closing(object sender, FormClosingEventArgs e)
{
string sqlUpdate = string.Format("update [User] set IsOnline='{0}' where Name='{1}'", 0, name); //SQL语句,更新isOnline为下线状态
/* 创建对象时使用using可以在使用完该对象后,自动释放资源 */
using (SqlConnection conn = new SqlConnection(connStr)) //创建数据库连接类
{
using (SqlCommand cmdUpdate = new SqlCommand(sqlUpdate, conn)) //创建数据库命令类
{
conn.Open(); //打开连接
//执行非查询命令时使用ExecuteNonQuery,会返回影响的行数
cmdUpdate.ExecuteNonQuery(); //执行SQL语句
conn.Close(); //关闭数据库连接
this.Hide();
}
}
}