学习了三层的理论知识后,接下来要通过实践深入的进行学习。本文以机房收费系统中登录窗体为例,进行三层开发实践。
登录
首先让我们回忆下登录窗体有什么,最简单的登录分为三个步骤,如下图。
步骤一、输入用户名,密码。点击登录
步骤二、登录成功提示信息,转换界面
步骤三、登录失败提示信息,重新输入
三层具体应用
DAL层:数据访问层,这一层我们有三个类,这三个类都起到,也只起到对数据库操作的功能和作用。
DbUtil类:连接数据库,使程序和数据库交互 |
ScoreDAO类:负责对数据库中Scores表的操作 |
UserDAO类:负责对数据库中Users表的操作 |
代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Login.DAL
{
class DbUtil
{
public static string ConnString = @"Server=DESKTOP-RUC7S1R; Database=Login; User ID=sa; Password=123456";
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;
namespace Login.DAL
{
public class ScoreDAO
{
public void UpdateScore(string userName, int value)
{
using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))
{
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = @"INSERT INTO SCORES(UserName, Score) Values(@UserName,@Score)";
cmd.Parameters.Add(new SqlParameter("@UserName", userName));
cmd.Parameters.Add(new SqlParameter("@Score", value));
conn.Open();
cmd.ExecuteNonQuery();
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace Login.DAL
{
public class UserDAO
{
public Login.Model.UserInfo SelectUser(string userName, string password)
{
using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))
{
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = @"SELECT ID, UserName,Password,Email
FROM USERS WHERE UserName=@UserName AND Password=@Password";
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add(new SqlParameter("@UserName", userName));
cmd.Parameters.Add(new SqlParameter("@Password", password));
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
Login.Model.UserInfo user = null;
while (reader.Read())
{
if (user == null)
{
user = new Login.Model.UserInfo();
}
user.ID = reader.GetInt32(0);
user.UserName = reader.GetString(1);
user.Password = reader.GetString(2); //not suggestion
if (!reader.IsDBNull(3))
{
user.Email = reader.GetString(3);
}
}
return user;
}
}
}
}
UI层:显示层,显示和接收用户对系统登录窗体输入的数据,为用户和界面提供交互
具体包括可输入的用户名和密码文本框,显示登录结果的代码
代码如下:
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 LoginUI
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnLogin_Click(object sender, EventArgs e)
{
//IDbConnection conn = new SqlConnection();
//IDbCommand cmd = conn.CreateCommand();
//cmd.CommandText = "";
//cmd.ExecuteReader();
string userName = txtUserName.Text.Trim();
string password = txtPassword.Text;
Login.BLL.LoginService mgr = new Login.BLL.LoginService();
Login.Model.UserInfo user = mgr.UserLogin(userName, password);
MessageBox.Show("登录用户: " +user.UserName);
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
Model:数据模型,它起到封装数据的作用,它独立于三层,目的是使数据可以在三个层次之间顺畅流转
这里面定义了程序涉及到的基本方法,如ID,UserName,Password,Email
代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Login.Model
{
//在三层之间传输数据
public class UserInfo
{
public int ID { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string Email { get; set; }
}
}
BLL层:业务逻辑层,主要负责对上述数据层的操作以及显示层的显示。
这里面把用户输入的用户名,密码等传到数据库中核对,显示登录状态的同时,又负责对数据表的更新
代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Login.BLL
{
public class LoginService
{
public Login.Model.UserInfo UserLogin(string userName, string password)
{
Login.DAL.UserDAO uDao = new Login.DAL.UserDAO();
Login.Model.UserInfo user = uDao.SelectUser(userName, password);
if (user != null) //login successfully
{
Login.DAL.ScoreDAO sDao = new Login.DAL.ScoreDAO();
sDao.UpdateScore(userName, 10);
return user;
}
else
{
throw new Exception("登录失败");
}
}
}
}
调错
当我输入已经保存在数据库中的用户名和密码后,出来了一个这个东西。
这个问题我在百度上一直没有查到,但我发现数据库Users表只有添加用户名和密码一致的用户才能显示登录成功,这个错误让我笑到了,我先查了自己的数据库,数据库并没有设置用户名和密码这两列内容必须一致,那么只有一个原因,我在代码中把Password的参数传到UserName中进行验证了,果然我在UserDAO类中找到了问题所在
画框中的userName改成password,问题便迎刃而解了。
提高效率的秘籍
问题是解决了,但出现问题的根源在哪里?在急功近利,在投机取巧。
绕了一大圈,最后的问题是代码错误了,如果我们在敲代码时不写注释,就向我一样,我们很难查到自己的错误在哪里;如果我们按照实例或者视频上的代码敲写而不去理解,我们对错误更加无从下手。
提高效率的秘籍就是在学习的过程中思考,假使我们的精力不足以支撑自己在某一时间段边学习,边思考,那不如请你抬起手来,先进行适当的休息。坑会让人进步,但无数次进同样的坑进步的代价可就花的太大了!