三层登录实战C#版

        刚开始接触三层的时候没头绪,虽然知道它们之间的引用关系,可是还是感觉很混乱,所以上网看了看博客,决定先从画图入手。从包图——>类图——>时序图(逻辑)——>代码,一步步的重新做!


一、包图

 三层登录实战C#版_第1张图片


       为什么要有实体层?没有实体层可以吗?为什么不叫四层,而叫三层呢?


       实体层的作用是便于层与层之间数据的传递,每个实体对象与数据库里的表示一一对应的。对于大量的数据来说,就可以直接通过实体对象用Get(),Set()方法将字段提取出来,这比临时在创建变量要省事。就相当于利用面向对象的思想,将大量的数据进行封装后在进行传递。


        例如:

         AddUser(UserID,UserName,UserPassword)

        用了实体层,将这些字段封装到UserInfo类中,可以写为AddUser(UserInfo),这样就省事多了。


        并不是一定要有实体层,如果只有少量数据, 例如机房收费系统中,查询某个卡号对应的学生,可以通过CardID作为参数来进行传递,也就没有必要用实体层进行传递了。


        实体层是为了数据传递提供方便,只是一个类,并无实际作用,可有可无,所以不可以和UI,DAL,BLL一样作为层来说。


二、类图


1、实体层 UserInfo类


三层登录实战C#版_第2张图片



2、D层:DbUtil类和UserDAO类



三层登录实战C#版_第3张图片



3、B层:LoginManager类


三层登录实战C#版_第4张图片


4、U层:FrmLogin类


三层登录实战C#版_第5张图片


三、时序图


三层登录实战C#版_第6张图片



四、代码

 
 
 
 

1、Entity层:UserInfo类


定义字段,获取字段的Get()与Set()方法,与数据库中的Users表是对应的,方便数据的传递

namespace LoginModel
{
    //数据库表的映射
        public class UserInfo
        {
            private string username;
            public string UserName
            {
                get { return username; }
                set { username = value; }
            }

            private string password;
            public string PassWord
            {
                get { return password; }
                set { password = value; }
            }

            public UserInfo(string username, string password)
            {
                this.username = username;
                this.password = password;
            }
        }
    
}



2、D层:


(1)DbUtil类:


namespace LoginDAL
{
    /// <summary>
    /// 创建连接数据库字符串
    /// </summary>
    class DbUtil
    {
       public static string ConnString = @"server=bill\BILLSQL;dataBase=Users;user id=sa;password=123456";
    }
}



(2)UserDAO类:


主要用于提供数据库的基本访问,供BLL调用。


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;

namespace LoginDAL
{ 
    public class UserDAO
    {
        //查询用户
         public LoginModel.UserInfo SelectUser(string username, string password)
        {

            using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))//创建SQL数据库打开连接
      
            {

                SqlCommand cmd = conn.CreateCommand(); //创建并返回一个与 SqlConnection 关联的 SqlCommand 对象

                cmd.CommandText = @"select username,password from user_Info where username=@username and password=@password";//获取数据源执行的查询语句

                cmd.CommandType = CommandType.Text;//设置一个值用来解释CommandText属性

                //将指定的SqlParameter添加到SqlParameterCollection中
                cmd.Parameters.Add(new SqlParameter("@username", username));
                cmd.Parameters.Add(new SqlParameter("@password", password));
                
                
                conn.Open();//打开数据库连接


                SqlDataReader reader = cmd.ExecuteReader();//将 CommandText 发送到 Connection 并生成一个 SqlDataReader

                LoginModel.UserInfo user = null;
               
               //使 SqlDataReader 前进到下一条记录
                while (reader.Read())
                {
                    if (user == null)
                    {
                        user = new LoginModel.UserInfo();
                    }
                   
                   user.UserName = reader.GetString(0);
                   user.PassWord = reader.GetString(1);

                }
                return user;
            }
        }
    }
}



3、B层:LoginManager类


处理业务逻辑,主要包括判断用户名与密码的是否为空,以及从D层中获取的数据传递给实体层。


namespace LoginBLL
{
    public class LoginManager
    {
         public LoginModel.UserInfo UserLogin(string username, string password)
        {
             //throw new NotImplementedException();
             
             LoginDAL.UserDAO uDAO = new LoginDAL.UserDAO();


             //用户名不能为空
            if (username == null)
            {
                throw new Exception("请输入用户名");

            }

             //密码不能为空
            if (password == null)
            {
                throw new Exception("请输入密码");

            }

            LoginModel.UserInfo user = uDAO.SelectUser(username, password);
            if (user != null)
            {
                
                return user;
                
            }
            else
            {
                throw new Exception("登录失败");
            }
        }
    }
   
}



4、U层:FrmLogin类


主要是界面命令以及操作,接收B层传来的数据。


namespace LoginUI
{
    public partial class FrmLogin : Form
    {
        public FrmLogin()
        {
            InitializeComponent();
        }

        private void btnLogin_Click(object sender, EventArgs e)
        {
            string username = txtUserName.Text.Trim() ;
            string password = txtPassWord.Text;

            try
            {
                LoginBLL.LoginManager mgr = new LoginBLL.LoginManager();
                LoginModel.UserInfo user = mgr.UserLogin(username, password); 
                MessageBox.Show("登录用户:" + user.UserName);
            }

            catch (Exception err)

            {
                MessageBox.Show(err.Message.ToString());
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)//卸载窗体
        {
            Close();
        }

    }
}



五、收获

    虽然理论理解了理论,但是有的代码还是不太理解,尤其是传递数据的那块,调试的时候发现是这样的:在界面输入用户名和密码——>B层——>D层——>实体层——>D层——>B层——>界面显示登录成功!

    用户输入用户名和密码后,执行B层代码判断用户名和密码是否为空,实例化LoginManager类,调用它的UserLogin方法;跳到B层,实例化UserDAO类,并调用它的SelectUser方法;调到D层,创建连接数据库对象,……到实体层这又乱了,正在看这篇博客的大神们,你们帮帮忙吧!

   



你可能感兴趣的:(三层登录实战C#版)